各要素をループせずに、フライのSwift)でmap
を使用してオブジェクトの配列を変更できるようにしたい。
ここまではこのようなことができました(詳細は ここ :
gnomes = gnomes.map { (var gnome: Gnome) -> Gnome in
gnome.age = 140
return gnome
}
Erica Sadunと他の人たちのおかげで、新しい提案が通過し、Cスタイルのループを取り除き、ループ内でvar
を使用するようになりました。
私の場合、最初にvar
を削除するように警告が表示され、次にエラーが発生します。私のgnome
は定数です(当然)
私の質問は次のとおりです。map
内の配列、またはSwift 3.0)に完全に備えるために、新しいスタイルのループを変更するにはどうすればよいですか?
その構文を維持したい場合は、(可変の)一時変数を使用してください
gnomes = gnomes.map { (gnome: Gnome) -> Gnome in
var mutableGnome = gnome
mutableGnome.age = 140
return mutableGnome
}
(以下は、Gnome
が参照型である場合に続きます;クラス-Gnome
をどのように定義したかを示していないためです。ここで、値型(構造体)としてのGnome
、@ vadian:sの回答を参照)
var
の削除は、.map
を使用してreferenceの配列のmutableメンバーを変更しても効果がありません。 )オブジェクトを入力します。つまり、古いアプローチを使用するだけで済みます(ただし、.map
クロージャー署名のvar
は省略します)。
class Gnome {
var age = 42
}
var gnomes = [Gnome(), Gnome(), Gnome()]
gnomes = gnomes.map {
$0.age = 150
return $0
}
/* result */
gnomes.forEach { print($0.age) } // 3x 150
ただし、.map
の結果を新しい配列に割り当てるのではなく、元の配列を変更するだけの場合は、.forEach
よりも.map
の方が適切な選択となる可能性があります。
gnomes.forEach { $0.age = 140 }
/* result */
gnomes.forEach { print($0.age) } // 3x 140
与えられた:
struct Gnome {
var age: Int = 0
}
var gnomes = Array(count: 5, repeatedValue: Gnome())
... 2つのまともなオプションがあります。 1つ目は、@ vadianが言ったとおりです。
gnomes = gnomes.map{
var gnome = $0
gnome.age = 70
return gnome
}
2つ目は、「エージング」private
を制御し続け、呼び出しポイントでのマッピングを簡素化します。
struct Gnome {
private(set) var age: Int = 0
func aged(age: Int) -> Gnome {
var gnome = self
gnome.age = age
// any other ageing related changes
return gnome
}
}
gnomes = gnomes.map{ $0.aged(140) }
もちろん、参照型はまだプログラミングでの位置を占めており、この場合はより適している可能性があります。ここで発生している摩擦は、これらの構造をオブジェクトであるかのように処理しようとしていることを示しています。それが必要な動作である場合は、Gnome
をclass
として実装することを検討する必要があります。