Return Class 符合协议
Return Class conform to protocol
例如,我有一个代表品牌的协议
我在这个例子中有两个 class,Jbl 和 Columbo 符合 Brand 协议
建造者建造了一些东西,最后 return Jbl 或 Columbo 的名字 class
(在代码示例中使用 random 简化了构建内容)
在这个示例代码中,我们可以在打印结果中随机期待 Jbl Brand 或 Columbo Brand
但这不能编译错误:Protocol 'Brand' can only be used as a generic constraint because it has Self or associated type requirements
protocol Brand: AnyObject, Hashable {
var name: String { get }
}
extension Brand {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.name == rhs.name
}
}
class Jbl: Brand {
var name: String { "Jbl" }
}
class Columbo: Brand {
var name: String { "Columbo" }
}
class Builder {
func build() -> Brand { // Protocol 'Brand' can only be used as a generic constraint because it has Self or associated type requirements
if .random() {
return Jbl()
} else {
return Columbo()
}
}
}
var builder = Builder()
print(builder.build().name)
问题是,对于 build()
,您正在尝试 return 一种 Brand
,但 Hashable
有 Self
要求作为其一部分定义。这就是为什么您会收到有关“自我或关联类型要求”的错误。
一个可能的解决方案是使 Brand
不是 Hashable
本身,而是任何符合 Brand
和 的 class Hashable
将获得 Hashable
实现 for Brand
:
protocol Brand: AnyObject {
var name: String { get }
}
extension Brand where Self: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.name == rhs.name
}
}
但是,访问 build()
不会给您 hashValue
,因为只有 class 符合 Brand
和 Hashable
有hashValue
.
要解决此问题,请使 Jbl
和 Columbo
符合 Hashable
协议。然后在 Builder
class 中添加这样的函数 例如:
func getHashValue() -> Int {
if .random() {
return Jbl().hashValue
} else {
return Columbo().hashValue
}
}
被称为:
print(builder.getHashValue())
// Prints: -8479619369585612153
显然,每次重新启动应用程序时,此哈希值都会发生变化,因此不要依赖它来持久保存数据。
并且仅出于样式原因:您可能更喜欢使用以下内容并使 classes 仅符合 HashableBrand
:
typealias HashableBrand = Brand & Hashable
例如,我有一个代表品牌的协议
我在这个例子中有两个 class,Jbl 和 Columbo 符合 Brand 协议
建造者建造了一些东西,最后 return Jbl 或 Columbo 的名字 class (在代码示例中使用 random 简化了构建内容)
在这个示例代码中,我们可以在打印结果中随机期待 Jbl Brand 或 Columbo Brand
但这不能编译错误:Protocol 'Brand' can only be used as a generic constraint because it has Self or associated type requirements
protocol Brand: AnyObject, Hashable {
var name: String { get }
}
extension Brand {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.name == rhs.name
}
}
class Jbl: Brand {
var name: String { "Jbl" }
}
class Columbo: Brand {
var name: String { "Columbo" }
}
class Builder {
func build() -> Brand { // Protocol 'Brand' can only be used as a generic constraint because it has Self or associated type requirements
if .random() {
return Jbl()
} else {
return Columbo()
}
}
}
var builder = Builder()
print(builder.build().name)
问题是,对于 build()
,您正在尝试 return 一种 Brand
,但 Hashable
有 Self
要求作为其一部分定义。这就是为什么您会收到有关“自我或关联类型要求”的错误。
一个可能的解决方案是使 Brand
不是 Hashable
本身,而是任何符合 Brand
和 的 class Hashable
将获得 Hashable
实现 for Brand
:
protocol Brand: AnyObject {
var name: String { get }
}
extension Brand where Self: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.name == rhs.name
}
}
但是,访问 build()
不会给您 hashValue
,因为只有 class 符合 Brand
和 Hashable
有hashValue
.
要解决此问题,请使 Jbl
和 Columbo
符合 Hashable
协议。然后在 Builder
class 中添加这样的函数 例如:
func getHashValue() -> Int {
if .random() {
return Jbl().hashValue
} else {
return Columbo().hashValue
}
}
被称为:
print(builder.getHashValue())
// Prints: -8479619369585612153
显然,每次重新启动应用程序时,此哈希值都会发生变化,因此不要依赖它来持久保存数据。
并且仅出于样式原因:您可能更喜欢使用以下内容并使 classes 仅符合 HashableBrand
:
typealias HashableBrand = Brand & Hashable