有人可以解释下面的代码中发生了什么?它创建一个struct Either,它接受任意两个可选类型,并且(尝试)返回哪个不是nil,或者如果两个都不是nil则返回第一个.然而,当传递文字nil而不是nil变量时,它表现得很奇怪.我不明白为什么示例中的b4表现得像……
struct Either <T1,T2> { let first: T1? let second: T2? init(first: T1?,second: T2?) { self.first = first self.second = second } func either() -> Bool { return (self.first != nil) || (self.second != nil) } func which() -> Any? { if self.first != nil { return self.first } else if self.second != nil { return self.second } return nil } } var s1: String? = nil var s2: Int? = nil let b1 = Either(first: s1,second: s2) b1.either() // false b1.which() // {nil} s1 = "Hello" let b2 = Either(first: s1,second: s2) b2.either() // true b2.which() // {Some Hello} s1 = nil s2 = 7 let b3 = Either(first: s1,second: s2) b3.either() // true b3.which() // {Some 7} // all as expected,however let b4 = Either(first: nil,second: nil) b4.either() // true !!! <<<<<<<<<<<<<<<<<< b4.which() // {nil}
我认为它与“可选的选项”有关,但我不确定它是否符合预期.
解决方法
这已在Beta 3中修复,最后一种情况现在正确触发编译器错误,迫使您明确指定泛型类型
问题在于类型 – 从文字创建Either时:
let b4 = Either(first: nil,second: nil)
然后编译器无法推断出nil参数的类型.如果检查调试器,您将看到推断类型是一个名为_Nil的类型.
(lldb) p b4 (SwiftConsole.Either<_Nil,_Nil>) $R1 = { first = Some second = Some }
let x: _Nil = nil //this is not an optional
初始化器正在对它进行选择,因此将值设为Optional.some(nil),因为它是.some(…)值,将它与nil进行比较将为false.
我没有看到任何简单的通用解决方法,但在这种情况下,它将有助于明确指定泛型类型:
let b4 = Either<String,Int>(first: nil,second: nil)
我建议你报告一个错误,因为这只是愚蠢的.编译器应该反而触发错误,而不是推断一些导致未定义行为的特殊类型.
类型为Any会出现同样的问题,因为它也可以接受nil而不是可选的.
let x: Any = nil //this is not an optional Either<Any,Any>(first: nil,second: nil).which() //true !!!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。