回答:
Swiftの構造体は値で渡されますが、inout
修飾子を使用して配列を変更できます(以下の回答を参照)。クラスは参照によって渡されます。Array
そしてDictionary
Swiftでは構造体として実装されています。
NSArray
ためNSArray
、ofの使用はお勧めしません。
inout
Structsで使用する場合はどうなりますか?
関数パラメーター演算子の場合、次の
ように使用します。let(これはデフォルトの演算子なので、letを省略できます)でパラメーターを定数にします(つまり、ローカルコピーも変更できないことを意味します)。
varで変数にします(ローカルで変更できますが、関数に渡された外部変数には影響しません)。そして、それを
入出力パラメーターにするための入出力。インアウトとは、実際には、値ではなく参照によって変数を渡すことを意味します。そして、参照で値を受け入れるだけでなく、参照で渡すことも必要なので、& -foo(&myVar)
、単に代わりにありますfoo(myVar)
したがって、次のようにします。
var arr = [1, 2, 3]
func addItem(inout localArr: [Int]) {
localArr.append(4)
}
addItem(&arr)
println(arr) // it will print [1, 2, 3, 4]
正確には、これは単なる参照ではなく、外部変数の実際のエイリアスです。そのため、任意の変数タイプ、たとえば整数を使用してそのようなトリックを行うことができます(整数に新しい値を割り当てることができます)。このような基本的なデータ型を変更するのは混乱するかもしれません。
inout
位置は、すなわち変更されましたfunc addItem(localArr: inout [Int])
var
関数のパラメーター属性では使用できなくなりました。
インターフェイスBoxedArray<T>
を実装するArray
が、すべての関数を格納されたプロパティに委任する自分自身を定義します。など
class BoxedArray<T> : MutableCollection, Reflectable, ... {
var array : Array<T>
// ...
subscript (index: Int) -> T {
get { return array[index] }
set(newValue) { array[index] = newValue }
}
}
を使用するBoxedArray
場所ならどこでも使用できますArray
。の割り当てはBoxedArray
参照によって行われます。これはクラスであるため、格納されたプロパティへの変更は、Array
インターフェイスを介して、すべての参照に対して表示されます。
String
のサブタイプであるAny
あなたが場合はimport Foundation
、その後String
のサブタイプになりはAnyObject
。
Swiftバージョン3-4(XCode 8-9)の場合は、
var arr = [1, 2, 3]
func addItem(_ localArr: inout [Int]) {
localArr.append(4)
}
addItem(&arr)
print(arr)
何かのようなもの
var a : Int[] = []
func test(inout b : Int[]) {
b += [1,2,3,4,5]
}
test(&a)
println(a)
???
func test(b: inout [Int])
は...多分これは古い構文です。私は2016年にSwiftに参加しただけで、この回答は2014年からのものなので、以前は異なっていたのでしょうか?
もう1つのオプションは、アレイのコンシューマーに、必要に応じて所有者に要求することです。たとえば、次のようなものがあります。
class Account {
var chats : [String]!
var chatsViewController : ChatsViewController!
func InitViewController() {
chatsViewController.getChats = { return self.chats }
}
}
class ChatsViewController {
var getChats: (() -> ([String]))!
func doSomethingWithChats() {
let chats = getChats()
// use it as needed
}
}
その後、Accountクラス内で好きなだけ配列を変更できます。ビューコントローラークラスから配列も変更する場合、これは役に立たないことに注意してください。
使用inout
は1つの解決策ですが、配列は値型であるため、それほど迅速ではありません。文体的には、個人的には変異したコピーを返すことを好みます。
func doSomething(to arr: [Int]) -> [Int] {
var arr = arr
arr.append(3) // or likely some more complex operation
return arr
}
var ids = [1, 2]
ids = doSomething(to: ids)
print(ids) // [1,2,3]
inout
それはバッテリーを節約するので、それは普遍的により良いことをあなたが提案していると思ったと思いました。私が言うには、このソリューションの可読性、不変性、およびスレッドセーフは全体的に優れており、そのinoutは、ユースケースで保証されているまれなケースでのみ最適化として使用する必要があります。
account
、グローバル変数を作成してas のchats
プロパティを定義するだけになりました。ChatsViewController
var chats: [Chat] { return account.chats }