Element == StringProtocol 和 Element: StringProtocol 有什么区别?
What's the difference between Element == StringProtocol and Element: StringProtocol?
我一直看到有关如何扩展数组的不同语法。这是我看到的两个。谁能解释一下区别是什么?
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
?
简答: 在这个特定的 use-case,
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
}
然后我可以在 [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]
,这是一个“盒子”数组,其中每个盒子可以
持有符合该协议的类型的任何值:
let pArray: [MyProtocol] = [A(id: 10), B(id: 11)]
pArray.bar()
(有关详细信息,请参阅
关于那个。)但这不会编译
aArray.bar() // '[A]' is not convertible to 'Array<MyProtocol>'
除非数组被显式转换为[MyProtocol]
类型的数组:
(aArray as [MyProtocol]).bar()
创建一个新数组并且是一个 O(N)
操作,如中所述
above-mentioned 回答。反之亦然,
pArray.foo() // Using 'MyProtocol' as a concrete type conforming to protocol 'MyProtocol' is not supported
无法编译,因为 .
我一直看到有关如何扩展数组的不同语法。这是我看到的两个。谁能解释一下区别是什么?
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
?
简答: 在这个特定的 use-case,
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
}
然后我可以在 [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]
,这是一个“盒子”数组,其中每个盒子可以
持有符合该协议的类型的任何值:
let pArray: [MyProtocol] = [A(id: 10), B(id: 11)]
pArray.bar()
(有关详细信息,请参阅
aArray.bar() // '[A]' is not convertible to 'Array<MyProtocol>'
除非数组被显式转换为[MyProtocol]
类型的数组:
(aArray as [MyProtocol]).bar()
创建一个新数组并且是一个 O(N)
操作,如中所述
above-mentioned 回答。反之亦然,
pArray.foo() // Using 'MyProtocol' as a concrete type conforming to protocol 'MyProtocol' is not supported
无法编译,因为