我一直在看如何扩展数组的不同语法。以下是我看到的两个。有人可以解释一下有什么区别吗?
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 ;;使用通用约束
那你怎么说Element
是T
,其中T
符合StringProtocol
?
答案 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]
因为A
和B
符合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