我试图为我的个人项目实现一个网络模块,我遵循TDD。当我写测试用例时,我遇到了一个编译错误,我无法用Swift概念Map错误。我本可以很容易地忽略它,并以不同的方式完成实现。但我觉得这样做不对,因为我想知道错误的确切原因。
这是代码片段。
import UIKit
protocol HTTPClient {
var url: String? {get set}
func load()
}
class HTTPClientSpy: HTTPClient {
var url: String?
func load() {
}
}
class Feed {
let client: HTTPClient
init(client: HTTPClient) {
self.client = client
}
func loadFeed() {
client.url = "" //Compile Error -> Cannot assign to property: 'client' is a 'let' constant
client.load()
}
}
当我做了下面的更改,错误就消失了
class Feed {
let client: HTTPClientSpy
init(client: HTTPClientSpy) {
self.client = client
}
func loadFeed() {
client.url = "" //No compile errors
client.load()
}
}
Swift类是可变的。这意味着我们应该能够改变示例的属性,即使我们创建了一个对示例的常量引用。在这种情况下,似乎与协议一致性有关,我无法理解。
有人能解释一下这背后的理论吗?
1条答案
按热度按时间xqnpmsa81#
Swift类是可变的。这意味着我们应该能够改变示例的属性,即使我们创建了一个对示例的常量引用。
你说得对。但是 structs 也可以符合
HTTPClient
协议:如果
Feed
传递了SomeStruct
的一个示例,那么client.url = ""
将无法工作。通常情况下,如果使用let
声明变量,则不能更改结构类型变量的var
。编译器不知道
Feed
中的client
存储的是一个结构体还是一个类,所以它会尽量保证安全,不让你修改url
。您可以通过添加
: AnyObject
来确保只有类才能符合协议: