Swift의 불변 / 변형 컬렉션


88

저는 Swift 언어로 Mutable / immutable 객체 (Array, Dictionary, Sets, Data)의 생성을 이해하기 위해 Apple의 Swift 프로그래밍 가이드를 참조했습니다. 하지만 Swift에서 변경 불가능한 컬렉션을 만드는 방법을 이해할 수 없었습니다.

Objective-C에서 다음과 같은 Swift의 등가물을보고 싶습니다.

불변 배열

NSArray *imArray = [[NSArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];

가변 배열

NSMutableArray *mArray = [[NSMutableArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];
[mArray addObject:@"Fourth"];

불변 사전

NSDictionary *imDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];

가변 사전

NSMutableDictionary *mDictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];
[mDictionary setObject:@"Value3" forKey:@"Key3"];

답변:


115

배열

불변 배열 만들기

첫 번째 방법 :

let array = NSArray(array: ["First","Second","Third"])

두 번째 방법 :

let array = ["First","Second","Third"]

가변 배열 만들기

var array = ["First","Second","Third"]

배열에 객체 추가

array.append("Forth")


사전

불변 사전 만들기

let dictionary = ["Item 1": "description", "Item 2": "description"]

가변 사전 만들기

var dictionary = ["Item 1": "description", "Item 2": "description"]

사전에 새 쌍 추가

dictionary["Item 3"] = "description"

Apple Developer에 대한 추가 정보


12
"고정 길이"배열이 더 정확합니다. 불변하지 않습니다.
Sulthan 2014-06-07

1
immutable Dictionary은 진정으로 불변입니다 (배열의 반대)
Bryan Chen

@BryanChen 오 .. 감사합니다!
nicael 2014-06-07

@BryanChen 네, 제거하는 것을 잊었습니다 var.
nicael 2014-06-07

2
예. 이 질문과 답변 에서 배열의 불변성에 대한 자세한 정보 .
Matt Gibson

31

Swift는 대체품이 없습니다. NSArray Objective-C의 다른 컬렉션 클래스를 .

배열 및 사전 클래스가 있지만 "객체"유형 인 NSArray 및 NSDictionary에 비해 "값"유형이라는 점에 유의해야합니다.

차이는 미묘하지만 엣지 케이스 버그를 방지하는 데 매우 중요 할 수 있습니다.

신속하게 다음을 사용하여 "불변"배열을 만듭니다.

let hello = ["a", "b", "c"]

그리고 "변경 가능한"배열 :

var hello = ["a", "b", "c"]

가변 배열은 다음과 같이 수정할 수 있습니다. NSMutableArray .

var myArray = ["a", "b", "c"]

myArray.append("d") // ["a", "b", "c", "d"]

그러나 가변 배열을 함수에 전달할 수 없습니다.

var myArray = ["a", "b", "c"]

func addToArray(myArray: [String]) {
  myArray.append("d") // compile error
}

그러나 위의 코드는 NSMutableArray에서 작동합니다.

var myArray = ["a", "b", "c"] as NSMutableArray

func addToArray(myArray: NSMutableArray) {
  myArray.addObject("d")
}

addToArray(myArray)

myArray // ["a", "b", "c", "d"]

당신은 달성 할 수 있습니다 NSMutableArrayinout메소드 매개 변수 를 사용하여의 동작을 .

var myArray = ["a", "b", "c"]

func addToArray(inout myArray: [String]) {
  myArray.append("d")
}

addToArray(&myArray)

myArray // ["a", "b", "c", "d"]

현재 Swift 동작을 반영하기 위해이 답변을 2015-08-10 다시 작성했습니다.


1
이것은 분명히 지금 바뀌 었습니다. 상수 배열은 이제 진정으로 불변이며, 가변 배열은 이제 진정으로 변경 가능합니다. 으로 전달 되므로 다른 변수에 할당되거나 함수간에 전달 될 때 복사됩니다. 그러나 이것은 변경 가능성 또는 불변성과 관련이 없습니다.
Balthazar

또한 내 대답에서 언급했듯이 값으로 전달되는 것은 변경 가능성 / 불변성과 관련이 있습니다.
Abhi Beckert 2015 년

그러나 속성으로 배열에 액세스하는 경우 다른 개체에서 계속 수정할 수 있습니다. 변경 불가능한 배열의 이점 중 하나는 다른 객체가 원본을 수정할 수 있는지 여부에 대해 걱정하지 않고 안전하게 다른 객체로 전달할 수 있다는 것입니다. 이 문제는 객체가 값으로 전달 될 때 더 이상 존재하지 않습니다. 따라서 다른 의미 체계에는 다른 코딩 관행이 필요합니다. 편집 : 이제 게시물을 다시 작성 했으므로 동의합니다. wrt를 인식하는 데 차이가 중요하다는 데 동의합니다. 변경 가능한 컬렉션의 사용.
Balthazar

6

하나가 Array하나 개의 Dictionary스위프트를 입력합니다. 변경 가능성은 구성 방법에 따라 다릅니다.

var mutableArray = [1,2,3]
let immutableArray = [1,2,3]

즉, 변수에 할당을 생성하면 변경 가능하지만 상수에 할당을 생성하면 변경되지 않습니다.

경고 : 변경 불가능한 배열은 완전히 변경 불가능한 것은 아닙니다! 전체 길이가 아니라 내용을 변경할 수 있습니다!


1
참고 : 향후 베타에서 어레이 동작이 변경됩니다. 나는 모두가 쌓여 생각에 대한 하나
russbishop

@xenadu 소스? 베타에 대한 ETA?
아날로그 파일

죄송합니다. 출처가 없습니다. 그것은 컴파일러 팀원 중 한 명과의 토론에서 나왔습니다. 그는 또한 베타 2는 기본적으로 이미 몇 가지 버그 수정에 불과하며 WWDC 이후 피드백과 관련이 없다고 말했습니다.
russbishop

5

(모든) 개체 또는 변수를

'let' key word -> for "constan/Immutable" array, dictionary, variable, object..etc.

'var' key word -> for "Mutable" array, dictionary, variable, object..etc. 

더 자세한 정보를 원하시면

let 을 사용하여 상수를 만들고 var 를 사용하여 변수를 만듭니다. 상수 값은 컴파일 타임에 알 필요가 없지만 정확히 한 번 값을 할당해야합니다. 즉, 상수를 사용하여 한 번 결정하지만 여러 곳에서 사용하는 값의 이름을 지정할 수 있습니다. "

var myVariable = 42
myVariable = 50
let myConstant = 42

"The Swift Programming Language"를 읽으십시오.


음, Array의 경우 예상대로 작동하지 않습니다. stackoverflow.com/a/24319712/623710
macshome

3

에서와 같이 Array(Swift)로 작업 NSArray하려면 간단한 브리지 기능을 사용할 수 있습니다. 예:

var arr1 : Array = []

arr1.bridgeToObjectiveC().count

.NET에서도 동일하게 작동합니다 let.


0

Apple의 자체 문서에서 :

컬렉션의 가변성

배열, 집합 또는 사전을 생성하고이를 변수에 할당하면 생성 된 컬렉션이 변경 될 수 있습니다. 즉, 컬렉션을 만든 후 컬렉션에서 항목을 추가, 제거 또는 변경하여 컬렉션을 변경 (또는 변경) 할 수 있습니다. 반대로 배열, 집합 또는 사전을 상수에 할당하면 해당 컬렉션은 변경할 수 없으며 크기와 내용을 변경할 수 없습니다.

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID105

변경 불가능 / 변경 불가능 컬렉션의 다른 용도는 변경 가능 / 불변 콜렉션을 원하는 이유에 따라 다릅니다. 컬렉션은 Swift의 유형입니다. 즉, 다른 값에 할당되거나 다른 함수 / 메서드에 전달 될 때 내용이 복사됩니다. 따라서 수신 메서드 함수가 원래 배열을 변경할 수 있는지 여부에 대해 걱정할 필요가 없습니다. 따라서 예를 들어 클래스가 변경 가능한 컬렉션을 보유하고있는 경우 변경 불가능한 컬렉션을 반환 할 필요가 없습니다.


0

[수정 불가 및 불변]

Swift의 배열을 음소거 할 수 있습니다.

[let vs var, 값 vs 참조 유형]

Immutable collection [About] -변경할 수없는 컬렉션 구조입니다. 생성 후 추가, 제거, 수정할 수 없음을 의미합니다.

let + struct(예 Array: Set,, Dictionary)는 불변에 더 적합합니다.

NSArray내부 상태를 변경하는 인터페이스를 제공하지 않는 클래스 (예 :)가 있습니다.

그러나

class A {
    var value = "a"
}

func testMutability() {
    //given
    let a = A()
    
    let immutableArr1 = NSArray(array: [a])
    let immutableArr2 = [a]
    
    //when
    a.value = "aa"
    
    //then
    XCTAssertEqual("aa", (immutableArr1[0] as! A).value)
    XCTAssertEqual("aa", immutableArr2[0].value)
}   

오히려 unmodifiable배열입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.