【发布时间】:2019-07-23 21:17:57
【问题描述】:
我有一个结构,其成员名为 email,类型为 String,协议成员名为 email,类型为 String?。我认为让结构符合该协议应该是微不足道的,因为它具有必要的信息,但我被编译器阻止了。这是我在操场上整理的一个精简示例:
struct SimpleStruct {
let email: String
}
protocol SimpleProtocol {
var email: String? { get }
}
// Type 'SimpleStruct' does not conform to protocol 'SimpleProtocol'
extension SimpleStruct: SimpleProtocol {}
错误具体说:
候选人具有不匹配的类型“字符串”
它还提供了一个修复:
您要添加协议存根吗?
但不出所料,这会导致重新声明错误。
extension SimpleStruct: SimpleProtocol {
var email: String? {
// Invalid redeclaration of 'email'
}
}
我知道String 和Optional<String> 是不同的类型,但我希望简单地说SimpleStruct 符合SimpleProtocol 而无需额外代码应该编译,原因与我可以将字符串传递给一个需要可选字符串的函数。有人可以解释我为什么错了吗?
注意:我意识到我可以通过多种方式解决这个问题,最明显的是重命名 SimpleProtocol 中的 email 字段。但我想了解为什么这是必要的,并想知道是否有更优雅的解决方案。
【问题讨论】:
-
这基本上与Why can't a get-only property requirement in a protocol be satisfied by a property which conforms? 中的限制相同,除了协议类型的 get-only 属性要求由符合类型的属性满足,您正在寻找更通用的子类型关系。没有技术上的原因不可能,只是还没有实现(尽管不幸的是,现在的实现会带来源兼容性问题)。
-
@Hamish 感谢您链接到该问题,感谢您在此处回答的详细信息!
-
我会说惊喜是另一种方式。给定一个包装了 String 的 Optional,将 String 直接分配给它是合法的,这很奇怪。你已经习惯了,但它是基于语言中一些奇怪的机制。毕竟你不能在期望
Wrapper<String>的地方分配一个字符串。
标签: swift