gpt4 book ai didi

ios - 具有自定义运算符的 Swift 类流式 API 设计

转载 作者:搜寻专家 更新时间:2023-11-01 06:37:36 25 4
gpt4 key购买 nike

我想用自定义运算符和函数编写某种类似流利的 api。这是我正在寻找的示例:

var result = [Section]()

result +++= Section()
.appendTitle(title)
.appendPhotos(photos)

result +++= Section()
.appendSomething(sth)
.appendPhotos(photos)
.appendAnything()

return result

为此,我声明了两个自定义运算符:

infix operator +++{ associativity left precedence 95 }

func +++(lhs : [Section], rhs : Section) -> [Section] {
var result = lhs
result.append(rhs)
return result
}

infix operator +++= { associativity left precedence 95 }

func +++=(inout lhs : [Section], rhs : Section) {
lhs = lhs +++ rhs
}

当然还有 Section 结构的正确扩展:

extension Section {
mutating func appendTitle(title: String?) -> Section {
guard let unwrappedTitle = title
else { return self }

...

return self
}

mutating func appendPhotos(photos: [Photo]?) -> Section {
...
}

...
}

不幸的是,它没有按预期工作......

单独行 result+++= Section() 是正确的,但是当我添加 .append 时它无法编译。

第一条消息是:将“[Section]”类型的值传递给 inout 参数需要显式的“&”

然后我尝试在 result 前面放一个 & (但我从来没有为 a += 1 做过)有第二条消息:不能在不可变值上使用可变成员:函数调用返回不可变值

因此,如果有人可以提供帮助,我们将不胜感激。

我使用的是 Swift 2.2 和 Xcode 7。

最佳答案

好吧,您已经找到了解决方案。太好了!

但请允许我解释一下这里实际发生的事情。

让我们仔细看看您之前的实现。

extension Section {
mutating func appendTitle(title: String?) -> Section {

guard let unwrappedTitle = title else { return self }
self.title = unwrappedTitle
return self
}

mutating func appendPhotos(photos: [Photo]?) -> Section {
guard let unwrappedPhotos = photos else { return self }
self.photos = unwrappedPhotos
return self
}
}

我们知道(至少现在)运算符重载函数绝对没问题,没有错。

给定的扩展正在改变参数的值,因此它应该是变异的,而且确实是。那么错误的原因:

"Cannot use mutating member on immutable value: function call returns immutable value"

原因:调用“appendTitle”或“appendPhotos”时,它会返回 self 的副本。不完全相同的引用!

这是因为 swift 处理不变性的方式。如果某个值类型的成员属性的值发生更改,则会创建一个副本,并将该值分配给相应的成员。

因此,当您编写:Section().appendTitle(title).appendPhotos(photos)

Section() 返回 self 的副本,即 Section 的不可变版本。因此不能appendTitle 到它,或者一般不能改变它。

可以解决:

var section = Section()
section.appendTitle(标题).appendPhotos(照片)

但是现在 appendTitle(title) 返回一个 self 的副本,即 Section 的不可变版本。同样的问题仍然存在。

您所做的是,您没有使用 self 更改任何内容,而是创建了一个新实例,这次是使用 var 的可变实例。变异它并返回它。现在它不是 mutating self,因此它不需要是 mutating func

您提供的解决方案在这里运行良好,但实际上它是一个 hack,这里需要它来覆盖我现在所说的 Swift 中的“错误”。

其他解决方案可以将 struct Section 更改为 class Section。在那里您不需要创建 var result,只需更改属性并返回。

这是我对 SO 的第一个回答 :)

关于ios - 具有自定义运算符的 Swift 类流式 API 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39613477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com