已更新:包含完整代码
我有这个代码:
struct Set<T : Hashable>: Sequence {
var items: Dictionary<Int, T> = [:]
func append(o: T?) {
if let newValue = o {
items[newValue.hashValue] = newValue
}
}
func generate() -> TypeGenerator<T> {
return TypeGenerator ( Slice<T>( items.values ) )
}
}
我得到错误:
找不到接受所提供参数的“下标”重载。
对于行:
items[newValue.hashValue] = newValue
据我了解这是因为 newValue
的类型是 T
而不是 T?
,这意味着它不是可选的。这是因为用于访问键/值对的 Dictionary
的 subscript
定义为
subscript (key: KeyType) -> ValueType?
意味着它只能接受一个可选的作为值。在我的例子中,newValue
在验证它不是 nil
之后不是可选的。
但是可选的不包含非可选的吗?类型的可选不是类型 + nil
吗?
为什么可以接受所有内容 + nil
的类型会拒绝不能为 nil
的类型?
小说明:我检查 o
不是 nil
的原因是能够调用它的 hashValue
不能直接从可选或未包装的可选访问(o!.hashValue
抛出编译错误)。
我也不能用
替换分配行items[newValue.hashValue] = o
因为它已验证 o
不是一个值得分配的可选值,即使它不允许访问它的 hashValue
属性。
最佳答案
字典未定义为存储可选值。它只是接受可选值的赋值运算符,因为给它 nil
将从字典中删除整个键。
您遇到的问题是您正试图以非变异方法改变您的属性 items
。您需要将您的方法定义为变异:
mutating func append(o: T?) {
if let newValue = o {
items[newValue.hashValue] = newValue
}
}
将可选变量分配给非可选值当然没有问题:
var optionalString : String? = "Hello, World"
以同样的方式,将字典的键分配给非可选值是完全有效的:
var items : [Int:String] = [:]
items[10] = "Hello, World"
然后您可以将键分配给 nil 以从字典中完全删除键:
items[10] = nil
此外,我认为您对什么是 hashValue 以及如何使用它存在根本性的误解。您不应将 hashValue 的值作为键传递给字典。字典根据您提供的值调用 hashValue,因此您让字典采用 hashValue 的 hashValue。
不能保证一个 hashValue 将不同于所有其他不同值的 hashValues。换句话说,“A”的哈希值可以是与“B”相同的哈希值。字典非常复杂,可以处理这种情况,并且仍然可以为您提供特定键的正确值,但您的代码无法处理这种情况。
关于ios - Swift 中的非可选类型不应该包含可选类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24214752/