【问题标题】:Extend all types in Swift?在 Swift 中扩展所有类型?
【发布时间】:2014-06-24 18:29:56
【问题描述】:

浏览我发现的 Swift 库代码:

extension T! : Printable {
  var description: String { get }
}

sn-p 似乎用“描述”字段扩展了所有类型。 当我尝试在我的代码中做同样的事情时,我得到了错误:

example.swift:10:11: 非标称类型 'T!'无法扩展

protocol MyProtocol {
  // ...
}

extension T! : MyProtocol { // error: Non-nominal...
  // ...
}

类似的问题在:

但他们没有解决:

  • 这里发生了什么?为什么库代码可以,但我的代码……不行?
  • 是否所有类型或所有类型都符合特定协议?

【问题讨论】:

标签: generics swift


【解决方案1】:

首先,它并没有扩展所有类型。它扩展了T!,即ImplicitlyUnwrappedOptional<T>。所以它扩展了隐式展开的可选类型,而不是所有类型。

“标题”并不是真正的 Swift 代码;它是自动生成的。在某些情况下,自动标头生成器中可能存在错误,使其无法生成真正的 Swift 代码。不要太从字面上理解。

您在自动生成的“标题”中注意到的一件奇怪的事情是某些内置语法收缩的应用不一致 - 类型声明不使用收缩,但扩展使用:

struct Array<T>
extension T[]

enum Optional<T>
extension T?

struct ImplicitlyUnwrappedOptional<T>
extension T!

可能自动标头生成器中的某些代码过于贪婪地用它们的约定语法替换了上述类型。所以首先我们假设extension T! 实际上是extension ImplicitlyUnwrappedOptional&lt;T&gt;。

但是,extension ImplicitlyUnwrappedOptional&lt;T&gt; 也无法编译,并出现错误“使用未声明的类型 'T'”。事实上,在自动生成的“标题”中,我们发现了许多带有类型参数的扩展声明实例,例如extension Dictionary&lt;KeyType, ValueType&gt;,不能在 Swift 中编译。这是自动生成标头的另一个错误。

但是移除类型参数可以:

extension ImplicitlyUnwrappedOptional : MyProtocol {
  // ...
}

这正是this answer 中显示的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-27
    • 2019-03-05
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2020-05-04
    相关资源
    最近更新 更多