[arrays] Swift : 참조로 배열을 전달 하시겠습니까?

내가 스위프트를 통과하고 싶은가 Array account.chatschatsViewController.chats참조로 (그래서가 채팅을 추가 할 때 account.chats, chatsViewController.chats여전히 포인트를 account.chats). 즉, 길이가 account.chats변경 될 때 Swift가 두 배열을 분리하는 것을 원하지 않습니다 .



답변

Swift의 구조체는 값으로 전달되지만 inout수정자를 사용 하여 배열을 수정할 수 있습니다 (아래 답변 참조). 클래스는 참조로 전달됩니다. Array그리고 DictionarySwift에서는 구조체로 구현됩니다.


답변

함수 매개 변수 연산자의 경우 다음을 사용합니다.

let (기본 연산자이므로 let 을 생략 할 수 있음 )을 사용하여 매개 변수를 상수로 만듭니다.

var 를 변수로 만듭니다 (로컬로 수정할 수 있지만 함수에 전달 된 외부 변수에는 영향을주지 않습니다). 및

inout의는 그것에게 입출력 매개 변수를 확인합니다. 인-아웃은 실제로 값이 아닌 참조로 변수를 전달하는 것을 의미합니다. 그리고 그렇게 참조하여 패스를 통과, 참조 값을 받아도에 의해뿐만 아니라 필요 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]

정확히 말하면 이것은 단지 참조가 아니라 외부 변수에 대한 실제 별칭입니다. 따라서 모든 변수 유형으로 이러한 트릭을 수행 할 수 있습니다 (예 : 정수 (새 값 할당 가능)). 좋은 관행이며 이와 같은 기본 데이터 유형을 수정하는 것은 혼란 스러울 수 있습니다.


답변

인터페이스 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인터페이스를 통해 저장된 속성에 대한 변경 사항 은 모든 참조에 표시됩니다.


답변

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)

???


답변

한 가지 다른 옵션은 어레이 소비자가 필요에 따라 소유자에게 요청하도록하는 것입니다. 예를 들어 다음과 같은 내용이 있습니다.

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은 하나의 해결책이지만 배열이 값 유형이기 때문에 나에게 매우 신속하게 느껴지지 않습니다. 스타일 적으로 저는 개인적으로 변형 된 사본을 반환하는 것을 선호합니다.

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]