Element == StringProtocol与Element:StringProtocol之间的区别是什么?

时间:2018-03-10 07:07:05

标签: swift swift4 swift-extensions

我一直在看如何扩展数组的不同语法。以下是我看到的两个。有人可以解释一下有什么区别吗?

extension Array where Element == StringProtocol {
    func foo(){}
}

extension Array where Element:StringProtocol {
    func foo(){}
}

那有什么区别?

加成:

我试图编写一个与[String][Substring]一起使用的扩展程序,并建议我将其基于StringProtocol,因此上述内容。但是,如果我尝试做类似以下的事情......

func foo(separator:Character)

    for line in self{

        let components = line.split(separator: separator, maxSplits: 1, omittingEmptySubsequences: false)

        let prefix = components[0].replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression) // Only trim the end of the prefix
        let suffix = components.count > 1
            ? components[1].trimmingCharacters(in: .whitespaces) // Perform full trim on the suffix
            : nil
        ...
    }

}

我明白了......

  

会员'拆分'不能用于协议类型的值' StringProtocol&#39 ;;使用通用约束

那你怎么说ElementT,其中T符合StringProtocol

1 个答案:

答案 0 :(得分:0)

简答:在这个特定的用例中,

extension Array where Element: StringProtocol {}

是你想要的。它定义了T数组的扩展,其中T符合StringProtocol。另一方面,

extension Array where Element == StringProtocol {}

定义类型为[StringProtocol]的数组的扩展名 - 据我所知 - 由于该协议而无法创建 有相关的类型要求。

长答案:让我们为一个简单的协议执行此操作 没有关联类型:

protocol MyProtocol {
    var id: Int { get }
}

extension Array where Element: MyProtocol {
    func foo() {
        for elem in self { print(elem.id) }
    }
}

extension Array where Element == MyProtocol {
    func bar() {
        for elem in self { print(elem.id) }
    }
}

和符合协议的两种类型

struct A: MyProtocol {
    let id: Int
}
struct B: MyProtocol {
    let id: Int
}

然后我可以在foo()类型和[A]类型的数组上调用[B] 因为AB符合MyProtocol

let aArray = [A(id: 1), A(id: 2), A(id: 3)]
let bArray = [B(id: 4), B(id: 5), B(id: 6)]

aArray.foo()
bArray.foo()

另一方面,可以在类型数组上调用bar() [MyProtocol],这是一个“盒子”数组,每个盒子都可以 保留符合该协议的任何类型的值:

let pArray: [MyProtocol] = [A(id: 10), B(id: 11)]
pArray.bar()

(有关详细信息,请参阅Type conversion when using protocol in Swift 关于那个。)但这不编译

aArray.bar() // '[A]' is not convertible to 'Array<MyProtocol>'

除非将数组显式转换为类型为[MyProtocol]的数组:

(aArray as [MyProtocol]).bar()

创建一个新数组并且是O(N)操作,如中所述 上述答案。反之亦然,

pArray.foo() // Using 'MyProtocol' as a concrete type conforming to protocol 'MyProtocol' is not supported

无法编译,因为a protocol does not conform to itself