无法比较不透明类型的两个实例
Unable to compare two instances of opaque types
有趣的是,我们现在可以声明 return 具有关联类型的协议的值。
下面报错,我没看懂错误
protocol Plant: Equatable {
var maintenance: String { get }
}
struct Rose: Plant {
let height: Float // inches
let maintenance = "Water once a day."
}
struct Orchid: Plant {
let height: Float // inches
let maintenance = "Water once a month."
}
func makePlant1() -> some Plant {
Rose(height: 4)
}
func makePlant2() -> some Plant {
Orchid(height: 8)
}
let plant1: some Plant = makePlant1()
let plant2: some Plant = makePlant2()
func asdf() {
let condition: Bool = (plant1 == plant2) // error: ambiguous without more context
print(condition)
}
当您向 return some Plant
声明一个函数时,编译器将查看函数的内容以查看 returned 的真实类型,在您的示例中returning 不同的类型,Rose
和 Orchid
。
这打破了 Equatable
的要求,即 Self
必须相同,您使用 some
并不意味着此要求消失。
您收到的错误消息有点令人困惑,但如果您将其更改为
print(plant1 == plant2)
错误信息更丰富
Cannot convert value of type 'some Plant' (result of 'makePlant2()') to expected argument type 'some Plant' (result of 'makePlant1')
为了能够在此处使用==
,您需要使用由相同函数创建的对象
func makePlant1(_ value: Float) -> some Plant {
Rose(height: value)
}
let plant1 = makePlant1(4)
let plant2 = makePlant1(4)
let plant3 = makePlant1(6)
print(plant1 == plant2) // true
print(plant1 == plant3) // false
Here 是一篇关于 hackingwithswift.com
主题的内容丰富的文章
协议 Plant
符合 Equatable
。这意味着符合 Plant
的类型也符合 Equatable
.
Rose
符合Plant
,所以也是Equatable
:可以区分两个Rose。
与 Orchid
相同:您可以区分两个 Orchids。
但是你不能将 Rose
等同于 Orchid
:它们都遵循相同的协议,但它们不继承自相同的 class。
如果您尝试将相同类型的两个等同起来,它会起作用 - 请参阅下面的示例。
1) 等同于遵循相同协议的实例
protocol Plant: Equatable {
var maintenance: String { get }
}
struct Rose: Plant {
let height: Float // inches
let maintenance = "Water once a day."
}
struct Orchid: Plant {
let height: Float // inches
let maintenance = "Water once a month."
}
func makePlant2() -> some Plant {
Orchid(height: 8)
}
func makePlant3() -> some Plant {
Orchid(height: 10)
}
func compare() {
let plant2: Orchid = makePlant2() as! Orchid
let plant3: Orchid = makePlant3() as! Orchid
let conditionPlant: Bool = (plant3 == plant2) // both are Equatable of the same type
print(conditionPlant)
}
2) 等同于从同一类型继承的 classes
protocol Plant: Equatable {
var maintenance: String { get }
}
class Tree: Plant {
static func == (lhs: Tree, rhs: Tree) -> Bool {
lhs.name == rhs.name
}
let name: String
var maintenance = "Never"
init(name: String) {
self.name = name
}
}
class Oak: Tree { }
class Sequoia: Tree { }
func makeTree1() -> Tree {
Oak(name: "Shady oasis")
}
func makeTree2() -> Tree {
Sequoia(name: "Old woody")
}
func compare() {
let tree1 = makeTree1()
let tree2 = makeTree2()
let conditionTree: Bool = (tree1 == tree2) // both are Equatable, inherit from the same type
print(conditionTree)
}
有趣的是,我们现在可以声明 return 具有关联类型的协议的值。
下面报错,我没看懂错误
protocol Plant: Equatable {
var maintenance: String { get }
}
struct Rose: Plant {
let height: Float // inches
let maintenance = "Water once a day."
}
struct Orchid: Plant {
let height: Float // inches
let maintenance = "Water once a month."
}
func makePlant1() -> some Plant {
Rose(height: 4)
}
func makePlant2() -> some Plant {
Orchid(height: 8)
}
let plant1: some Plant = makePlant1()
let plant2: some Plant = makePlant2()
func asdf() {
let condition: Bool = (plant1 == plant2) // error: ambiguous without more context
print(condition)
}
当您向 return some Plant
声明一个函数时,编译器将查看函数的内容以查看 returned 的真实类型,在您的示例中returning 不同的类型,Rose
和 Orchid
。
这打破了 Equatable
的要求,即 Self
必须相同,您使用 some
并不意味着此要求消失。
您收到的错误消息有点令人困惑,但如果您将其更改为
print(plant1 == plant2)
错误信息更丰富
Cannot convert value of type 'some Plant' (result of 'makePlant2()') to expected argument type 'some Plant' (result of 'makePlant1')
为了能够在此处使用==
,您需要使用由相同函数创建的对象
func makePlant1(_ value: Float) -> some Plant {
Rose(height: value)
}
let plant1 = makePlant1(4)
let plant2 = makePlant1(4)
let plant3 = makePlant1(6)
print(plant1 == plant2) // true
print(plant1 == plant3) // false
Here 是一篇关于 hackingwithswift.com
主题的内容丰富的文章协议 Plant
符合 Equatable
。这意味着符合 Plant
的类型也符合 Equatable
.
Rose
符合Plant
,所以也是Equatable
:可以区分两个Rose。
与 Orchid
相同:您可以区分两个 Orchids。
但是你不能将 Rose
等同于 Orchid
:它们都遵循相同的协议,但它们不继承自相同的 class。
如果您尝试将相同类型的两个等同起来,它会起作用 - 请参阅下面的示例。
1) 等同于遵循相同协议的实例
protocol Plant: Equatable {
var maintenance: String { get }
}
struct Rose: Plant {
let height: Float // inches
let maintenance = "Water once a day."
}
struct Orchid: Plant {
let height: Float // inches
let maintenance = "Water once a month."
}
func makePlant2() -> some Plant {
Orchid(height: 8)
}
func makePlant3() -> some Plant {
Orchid(height: 10)
}
func compare() {
let plant2: Orchid = makePlant2() as! Orchid
let plant3: Orchid = makePlant3() as! Orchid
let conditionPlant: Bool = (plant3 == plant2) // both are Equatable of the same type
print(conditionPlant)
}
2) 等同于从同一类型继承的 classes
protocol Plant: Equatable {
var maintenance: String { get }
}
class Tree: Plant {
static func == (lhs: Tree, rhs: Tree) -> Bool {
lhs.name == rhs.name
}
let name: String
var maintenance = "Never"
init(name: String) {
self.name = name
}
}
class Oak: Tree { }
class Sequoia: Tree { }
func makeTree1() -> Tree {
Oak(name: "Shady oasis")
}
func makeTree2() -> Tree {
Sequoia(name: "Old woody")
}
func compare() {
let tree1 = makeTree1()
let tree2 = makeTree2()
let conditionTree: Bool = (tree1 == tree2) // both are Equatable, inherit from the same type
print(conditionTree)
}