我试图扩展非正统的'类型'时看到这个错误(Int, Int),或者Any:
非名义类型"任何"不能扩展
那么什么使一种类型非名义?什么是一个非标称型等之间的差异Any或(Int)和常规标称型样Int?
Bre*_*don 70
在目前接受的答案是不正确; 实际的答案来自Swift类型系统的深刻而深奥的部分.
Swift中的大多数类型都是名义类型 -它们是在特定模块中声明的"命名"类型,作为用户代码的一部分.看似原始的类型Int,Array并且实际上是Swift模块中定义的结构,它自动导入到每个Swift源文件中.即使Optional它本身也是Swift模块中的枚举,尽管编译器添加了一些魔法,如可选链接和强制解包.
少数例外称为"非名义类型".可能还有其他人,但主要是:
(Int) -> String(Int, String)String.Type类型,如(表达式的类型String.self)CustomStringConvertible & Error存在感应该得到更多的解释.存在主义包含一个值,其精确类型已被抽象出来,但已知它符合某组协议.例如:
// You can put anything that conforms to `CustomStringConvertible` in `x`
let x: CustomStringConvertible
// You can put anything that conforms to both `CustomStringConvertible`
// and `Error` in `y`
let y: CustomStringConvertible & Error
// You can put anything in `z`; `Any` is an existential that doesn't
// require you to conform to any particular protocols
let z: Any
Run Code Online (Sandbox Code Playgroud)
非名义类型都只是以某种特殊的方式将其他类型组合在一起.(它们有时被称为"结构类型",因为它们为其他类型定义某种通用结构以插入.)它们不需要显式定义,并且它们不属于任何特定模块 - FooKit (Int, String)是和BarKit一样(Int, String).但是它们的所有行为都是由语言定义的 - 非名义类型不能拥有自己的方法或属性,不能符合协议,因此无法扩展.
因此,您无法扩展,Any因为它Any是一种内置于语言中的特殊内容,就像函数类型或元组类型一样.它碰巧有一个用字母写的名字,而不是用标点符号.
(那么为什么你可以扩展CustomStringConvertible?因为,根据上下文,CustomStringConvertible可能意味着协议或它可能意味着包含符合协议的值的存在性.当你写extension CustomStringConvertible,你扩展协议,但是当你写let x: CustomStringConvertible,你是声明一个变量,其类型为"存在性,包含符合协议的值".这有点令人困惑,Swift的一些维护者实际上希望要求存在性写入Any<CustomStringConvertible>以使其更清晰.不太可能发生但是现在他们正试图保持源稳定性.)
这有点猜测(编辑:这是错误的,看看布伦特的答案),但这里是:
Any是一个协议,而不是实际类型。“名义”一词意味着命名(基于词根)。
因此,您无法扩展,Any因为它是协议,而不是实际类型,并且您无法扩展(Int, Int),因为它只是一个元组文字,也不是您可以通过名称指定的实际类型。
当然,您可以扩展协议。Any不是一个协议,它是(令人震惊的)一种非名义类型,这是别的东西。阅读布伦特的回答;他做得很好。
| 归档时间: |
|
| 查看次数: |
6355 次 |
| 最近记录: |