Ios 不应该';Swift中的可选类型不包括非可选类型吗?

Ios 不应该';Swift中的可选类型不包括非可选类型吗?,ios,dictionary,swift,optional,Ios,Dictionary,Swift,Optional,更新:带有完整代码 我有以下代码: struct Set<T : Hashable>: Sequence { var items: Dictionary<Int, T> = [:] func append(o: T?) { if let newValue = o { items[newValue.hashValue] = newValue } } func generate() -

更新:带有完整代码

我有以下代码:

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 ) )
    }
}
据我所知,这是因为
newValue
的类型是
T
,而不是
T?
,这意味着它不是可选的。这是因为用于访问键/值对的
字典
下标
被定义为

subscript (key: KeyType) -> ValueType?
这意味着它只能接受一个可选值作为值。在我的例子中,
newValue
在验证后不是可选的,它不是
nil

但是可选的不包括非可选的吗?类型不是可选的吗?类型是+
nil

为什么可以接受一切+
nil
的东西会拒绝不能是
nil
的类型

小说明:我检查
o
是否为
nil
的原因是能够调用其
hashValue
,该值不能直接从可选或未包装的可选调用(
o!.hashValue
引发编译错误)

我也不能用替换任务行

items[newValue.hashValue] = o

因为它已经验证了
o
不是一个值得赋值的可选值,即使它不允许访问它的
hashValue
属性。

您确实可以在
字典中存储一个非可选值
,通常只要需要
T?
类型的对象,您就可以传递它

真正的问题是您没有告诉编译器
t
可散列的

您必须使用
T:Hashable
T
上设置类型约束。您可以在类级别执行此操作(我假设此方法存在于泛型类中),如下所示

class-Foo{
变量项:字典=[:]
函数附加(o:T?){
如果让newValue=o{
items[newValue.hashValue]=newValue
}
}
}

字典未定义为存储可选值。只有赋值运算符才接受可选值,因为赋予它
nil
将从字典中删除整个键

您遇到的问题是,您正试图以非变异方法变异属性
。您需要将方法定义为变异:

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"
同样,将字典的键指定给非可选值也是完全有效的:

var optionalString : String? = "Hello, World"
var items : [Int:String] = [:]
items[10] = "Hello, World"
然后,您可以将密钥分配给nil以从字典中完全删除密钥:

items[10] = nil
另外,我认为您对hashValue是什么以及如何使用它有一个基本的误解。不应将hashValue的值作为键传递给字典。字典根据您提供的值调用hashValue,因此您让字典获取hashValue的hashValue


不能保证hashValue与其他所有不同值的hashValue不同。换句话说,“A”的散列值可以是与“B”相同的散列值。字典足够复杂,可以处理这种情况,并且仍然为特定键提供正确的值,但您的代码无法处理这种情况。

您好,我不明白您的问题,以下内容适用于我
class X{var items:dictionary=[:]func append(o:T?{if let newValue=o{items[newValue.hashValue]=newValue}}}var x=x()var s=“a”var so:String?=“b”变量子:字符串?=nil x.append(s)x.append(so)x.append(son)for(u,v)in x.items{println(v)}
let将
T?
转换为
T
您得到的错误是什么?我更新了我的答案,现在您给了我们实际的错误,我理解关于散列值的问题。我之所以使用它,是因为我没有看到Swift所拥有的集合的愚蠢实现。我使用字典进行快速查找,然后相应地存储值。这只是Swift中的一个小练习,而不是生产代码。@AvihuTurzion好的,只要您了解您有可能用新值覆盖旧值unintentionally@AvihuTurzion,但只要将该方法标记为“mutating”,就可以修复即时编译错误,只要它们有正确的错误。我找错了东西:/@AvihuTurzion Ya,swift中的错误肯定需要一些重要的工作。一个很好的经验法则是,当您遇到关于运算符(如下标)的错误时,请将代码切换为使用长名称。在本例中,将代码更改为items.updateValue(newValue,newValue.hashValue)会导致错误“Dictionary类型的不可变值只有名为‘updateValue’的变异成员抱歉搞砸了,我应该首先包括整个代码。我已经告诉编译器,
T
是可散列的。问题是,据我所知,
items[Int]=T?
我正在分配
T