在 Swift 中绕过 let 参数
Getting around let arguments in Swift
这是一个简单的游乐场示例:
class Foobar {
var name = ""
init(name:String) {
self.name = name
}
func modifyName(modification:String) {
self.name += modification
}
}
let list = [Foobar(name:"I"), Foobar(name:"Me"), Foobar(name:"Myself")]
for each in list {
each.modifyName(" rules")
}
一个 class 和 name
变量,以及一个可以修改该变量的函数。列一个表,现在用一个for in
来练习修改功能
但是。如果我将 modifyName 变量重构为协议扩展:
class Foobar {
var name = ""
init(name:String) {
self.name = name
}
}
protocol Modifiable {
var name:String { get set }
}
extension Modifiable {
mutating func modifyName(modification:String) {
self.name += modification
}
}
extension Foobar:Modifiable { }
然后 for in
将不再起作用,因为 Modifiable
扩展需要将 modifyName
注释为 mutating
。发出的错误是 error: cannot use mutating member on immutable value: 'each' is a 'let' constant
。有一个简单的解决方法,但感觉我在滥用某些东西:
for each in list {
var each = each
each.modifyName(" rules")
}
我遇到过同样的问题,函数的参数已被注释标记。过去,您可以在 arg 列表中用 var
标记这些参数,但在最新版本的 swift 中已弃用。同样的单行解决方法在那里工作。有没有更好更惯用的方法来做到这一点?最初开始这个,只是将一些常见的行为提取到协议扩展中,而不是继承树。感觉就像我在为那个选择付出代价。
否,您的单行解决方法不一定有效。您的协议不要求符合类型是引用类型 (类)。如果一个结构符合你的协议,并且在数组中,var each = each
会制作一个 copy,修改副本不会修改数组中的值。
您可以要求您的对象是 类、protocol Modifiable: class
,在这种情况下我相信 mutating
将不再被允许(或者,至少您的代码将正常工作) .
但假设你想保留 mutating
,你可以这样做来修改原地的元素:
for i in list.indices {
list[i].modifyName()
}
当然,你的数组也必须是var
,因为它也是一个结构value semantics。
这是一个简单的游乐场示例:
class Foobar {
var name = ""
init(name:String) {
self.name = name
}
func modifyName(modification:String) {
self.name += modification
}
}
let list = [Foobar(name:"I"), Foobar(name:"Me"), Foobar(name:"Myself")]
for each in list {
each.modifyName(" rules")
}
一个 class 和 name
变量,以及一个可以修改该变量的函数。列一个表,现在用一个for in
来练习修改功能
但是。如果我将 modifyName 变量重构为协议扩展:
class Foobar {
var name = ""
init(name:String) {
self.name = name
}
}
protocol Modifiable {
var name:String { get set }
}
extension Modifiable {
mutating func modifyName(modification:String) {
self.name += modification
}
}
extension Foobar:Modifiable { }
然后 for in
将不再起作用,因为 Modifiable
扩展需要将 modifyName
注释为 mutating
。发出的错误是 error: cannot use mutating member on immutable value: 'each' is a 'let' constant
。有一个简单的解决方法,但感觉我在滥用某些东西:
for each in list {
var each = each
each.modifyName(" rules")
}
我遇到过同样的问题,函数的参数已被注释标记。过去,您可以在 arg 列表中用 var
标记这些参数,但在最新版本的 swift 中已弃用。同样的单行解决方法在那里工作。有没有更好更惯用的方法来做到这一点?最初开始这个,只是将一些常见的行为提取到协议扩展中,而不是继承树。感觉就像我在为那个选择付出代价。
否,您的单行解决方法不一定有效。您的协议不要求符合类型是引用类型 (类)。如果一个结构符合你的协议,并且在数组中,var each = each
会制作一个 copy,修改副本不会修改数组中的值。
您可以要求您的对象是 类、protocol Modifiable: class
,在这种情况下我相信 mutating
将不再被允许(或者,至少您的代码将正常工作) .
但假设你想保留 mutating
,你可以这样做来修改原地的元素:
for i in list.indices {
list[i].modifyName()
}
当然,你的数组也必须是var
,因为它也是一个结构value semantics。