Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
即使使用相同的swift版本,Xcode 9和Xcode 10也会给出不同的结果_Swift_Xcode_Xcode10 - Fatal编程技术网

即使使用相同的swift版本,Xcode 9和Xcode 10也会给出不同的结果

即使使用相同的swift版本,Xcode 9和Xcode 10也会给出不同的结果,swift,xcode,xcode10,Swift,Xcode,Xcode10,我在xcode 9.3和xcode 10 beta 3中运行这段代码 import Foundation public protocol EnumCollection: Hashable { static func cases() -> AnySequence<Self> } public extension EnumCollection { public static func cases() -> AnySequence<Self>

我在xcode 9.3和xcode 10 beta 3中运行这段代码

import Foundation

public protocol EnumCollection: Hashable {
    static func cases() -> AnySequence<Self>
}

public extension EnumCollection {

    public static func cases() -> AnySequence<Self> {
        return AnySequence { () -> AnyIterator<Self> in
            var raw = 0
            return AnyIterator {
                let current: Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: self, capacity: 1) { $0.pointee } }

                guard current.hashValue == raw else {
                    return nil
                }

                raw += 1
                return current
            }
        }
    }
}

enum NumberEnum: EnumCollection{
    case one, two, three, four
}

Array(NumberEnum.cases()).count
<代码>导入基础 公共协议枚举集合:可哈希{ 静态func cases()->AnySequence } 公共扩展枚举集合{ public static func cases()->AnySequence{ 在中返回AnySequence{()->AnyIterator var原始值=0 返回任意迭代器{ 让current:Self=withUnsafePointer(to:&raw){$0.withMemoryRebound(to:Self,capacity:1){$0.pointee} guard current.hashValue==原始else{ 归零 } 原始+=1 回流 } } } } enum NumberEnum:枚举集合{ 案例一,案例二,案例三,案例四 } 数组(numbernum.cases()).count 尽管他们都在使用swift 4.1,但他们给了我不同的结果

在xcode 9.3上 数组大小为4

在xcode 10 beta 3上 数组的大小为0


我完全不理解这一点。

这是一种获取所有枚举值序列的未记录方法, 只是在早期的Swift版本中偶然出现。它依赖于 枚举值的哈希值为连续整数, 从零开始

这显然不再适用于Swift 4.2(即使正在运行) 在Swift 4兼容模式下),因为哈希值现在总是 请参阅:

为了降低散列值的可预测性,默认情况下,标准散列函数使用每次执行的随机种子

你可以用

print(NumberEnum.one.hashValue)
print(NumberEnum.two.hashValue)
它不使用Xcode 10打印
0
1
,但有些 其他值也随每个程序的运行而变化

有关正确的Swift 4.2/Xcode 10解决方案,请参阅:


下面是针对Xcode 10和Swift 4.2及以上版本的解决方案

步骤1:创建协议可枚举

protocol EnumIterable: RawRepresentable, CaseIterable {
    var indexValue: Int { get }
}

extension EnumIterable where Self.RawValue: Equatable {
    var indexValue: Int {
        var index = -1
        let cases = Self.allCases as? [Self] ?? []
        for (caseIndex, caseItem) in cases.enumerated() {
            if caseItem.rawValue == self.rawValue {
                index = caseIndex
                break
            }
        }
        return index
    }
}
步骤2:将EnumIterator协议扩展到您的枚举

enum Colors: String, EnumIterable {
    case red = "Red"
    case yellow = "Yellow"
    case blue = "Blue"
    case green = "Green"
}
步骤3:使用indexValue属性,就像使用hashValue一样

Colors.red.indexValue
Colors.yellow.indexValue
Colors.blue.indexValue
Colors.green.indexValue
打印语句和输出示例

print("Index Value: \(Colors.red.indexValue), Raw Value: \(Colors.red.rawValue), Hash Value: \(Colors.red.hashValue)")
输出:“索引值:0,原始值:红色,哈希值:1593214705812839748”

输出:“索引值:1,原始值:黄色,散列值:-6836447220368660818”

输出:“索引值:2,原始值:蓝色,散列值:-8548080225654293616”


输出:“索引值:3,原始值:绿色,哈希值:6055121617320138804”

如果使用枚举的哈希值来确定大小写值(位置或id),这是一种错误的方法,因为它不能保证返回顺序的int值,0,1,2。。。从swift 4.2开始,它不再工作

例如,如果使用如下枚举:

enum AlertResultType {
    case ok, cancel 
}
此枚举的hashValue可能返回一个大的int值,而不是0(确定)和1(取消)

因此,您可能需要更精确地声明枚举类型并使用rowValue。比如说

enum AlertResultType : Int {
    case ok = 0, cancel = 1
}

谢谢你的更正。只是为了我的理解,所以逻辑散列函数在swift中,对吗?xcode版本会有什么变化?@kr15hna:它是Swift标准库或Swift运行时的一部分,两者都随xcode应用程序一起提供。因此,即使我在xcode 10中运行4.1,它也不起作用,因此这4.1与xcode 9 4.1不同。@kr15hna:不。xcode 10随Swift 4.2一起提供,并且具有Swift 3和4的兼容模式。
print("Index Value: \(Colors.blue.indexValue), Raw Value: \(Colors.blue.rawValue), Hash Value: \(Colors.blue.hashValue)")
print("Index Value: \(Colors.green.indexValue), Raw Value: \(Colors.green.rawValue), Hash Value: \(Colors.green.hashValue)") 
enum AlertResultType {
    case ok, cancel 
}
enum AlertResultType : Int {
    case ok = 0, cancel = 1
}