【问题标题】:Is there a way to make this function generic?有没有办法使这个函数通用?
【发布时间】:2021-03-27 17:17:21
【问题描述】:

我有一个数据集:

struct MyData {
  var name: String
  var date: Date
  var quantity: Int
  var inStock: Bool
} 

然后在数组中使用它

let myArray: [MyData] = [...]

我目前正在编写更改值的方法..

func changeName(to newName: String) { myArray[0].name = newName }

func changeDate(to newDate: Date) { myArray[0].date = newDate }

func changeQuantity(to newQuantity: Int) { myArray[0].quantity = newQuantity}

我开始认为这对于泛型来说是一个完美的案例,并说类似

func changeValue<Value>(to newValue: Value) { ... }

唯一的问题是我不能使 点符号 通用

如果我能说

myArray[0].value = newValue

任何关于此事的指导都会有所帮助!

【问题讨论】:

  • 我没有时间写答案,但请查找“关键路径”。
  • 你为什么需要这个? myArray.change(value: \.name, to: "new name")myArray[0].name = "new name" 有什么优势?
  • 如果有两个相同类型的属性怎么办?
  • @SergioBost 我看不到编写方法来更改元素属性的任何优势。顺便说一句,您需要首先将它们声明为变量而不是常量。如果你真的想使用关键路径,你只需要myArray[0][keyPath: \.name] = "whatever",但 IMO 更容易按照 Martin R 建议的myArray[0].name = "whatever"
  • @SergioBost 这很明显。我的意思是不通过密钥路径

标签: swift generics


【解决方案1】:

如果您var 声明您的属性,您可以将以下函数添加到您的结构中

mutating func setValue<Value>(_ value: Value, for keyPath: WritableKeyPath<Self, Value>) {
    self[keyPath: keyPath] = value
}

然后像这样使用它

var myData = MyData(name: "abs", date: Date(timeIntervalSince1970: 0), quantity: 0, inStock: false)

myData.setValue(500, for: \.quantity )
myData.setValue(Date(), for: \.date)
myData.setValue(true, for: \.inStock)

这将更新对象

MyData(name: "abs", date: 2021-03-27 18:26:26 +0000, 数量: 500, inStock: true)

那么你想如何将它用于你的数组对我来说有点不清楚,但在这里你至少有一个工具可以使用。

【讨论】:

  • 是的!如果我能不止一次地给你投票,我会的。这正是我一直在寻找的。旁注:我不明白为什么人们对一个问题投反对票,这是一回事,因为为什么要让提问者感到羞耻......无论如何谢谢!
  • @SergioBost 为什么不简单地 myData.quantity = 500 ?除了说教之外,我不明白这种方法的目的
  • @LeoDabus 好吧,如果我只有一个属性要更新,那么我同意它毫无意义,但我的问题的全部目的是避免必须编写一个函数来更新每个属性。使用上面的这段代码,我可以用一种方法做到这一点。而且我认为您的方法也可以,但是效果相似,代码行数更少
  • 抱歉,您不需要为此提供方法。您可以简单地将下标与属性一起使用,通常您可能需要一次更新多个属性
猜你喜欢
  • 2021-06-05
  • 2022-01-07
  • 2017-11-29
  • 2019-09-10
  • 2020-07-31
  • 1970-01-01
  • 2014-12-11
  • 2019-10-10
  • 1970-01-01
相关资源
最近更新 更多