我不断看到关于如何扩展数组的不同语法。这是我看到的两个。谁能解释一下有什么区别吗?
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
...
}
}
我明白了...
Member 'split' cannot be used on value of protocol type 'StringProtocol'; use a generic constraint instead
那么你怎么说Element
是一个T
,其中T
符合StringProtocol
?
最佳答案
简短回答:在这个特定的用例中,
extension Array where Element: StringProtocol {}
就是你想要的。它定义了 T
数组的扩展,其中 T
符合 StringProtocol
。另一方面,
extension Array where Element == StringProtocol {}
定义了[StringProtocol]
类型数组的扩展,它是
– 据我所知 – 不可能创建,因为该协议(protocol)
有相关的类型要求。
长答案:让我们为一个简单的协议(protocol)执行此操作,该协议(protocol)具有 没有关联的类型:
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) }
}
}
以及符合协议(protocol)的两种类型
struct A: MyProtocol {
let id: Int
}
struct B: MyProtocol {
let id: Int
}
然后我可以对 [A]
类型和 [B]
类型的数组调用 foo()
因为 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]
,这是一个“盒子”数组,其中每个盒子可以
保存符合该协议(protocol)的类型的任何值:
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 .
关于swift - Element == StringProtocol 和 Element : StringProtocol? 之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49206354/