티스토리 뷰

Swift

Swift4 ) Swap / Law of Exclusivity

Zedd0202 2017. 12. 21. 19:42
반응형

안녕하세요 :) Zedd입니다.

다들 swap아시죠? 그 옛날에 정렬글과 Generic에서도 소개한 적 있죠. 

그래서...우리는..배열에서...서로 값을 바꿔야 하는 상황이 온다?

 

  1. var arr = [9,8,7,6,5,4,3,2,1]

    swap(&arr[0], &arr[1])


뭐 이런식으로 했었죠?

그런ㄴ데...!!

Swfit4에서는 조금 바뀌었습니다. 



Swift4에서 이렇게 Collection에 있는 것들을 swap할려고 하면 에러가 나게 됩니다.

왜냐? 이 swap이 Law of Exclusivity를 위반하기 때문입니다.

여기에  Law of Exclusivity의 설명을 포함한 Swift의 Ownership에 대한 자세한 설명이 있습니다. 




Law of Exclusivity는 원래 마케팅 용어에요.


출처 : https://navyofsoul.blog.me/220363757546


이러한 마케팅 용어가 Swift와 뭔상관..;;;???해서 알아봤는데

Law of Exclusivity를 간단하게 설명하자면, 변수가 동시에 충돌하는 방식으로 액세스 하지 못하게 하는것입니다. 

좀 더 자세하게 말하면,


If a storage reference expression evaluates to a storage reference that is implemented by a variable, then the formal access duration of that access may not overlap the formal access duration of any other access to the same variable unless both accesses are reads.


스토리지 참조 표현식(storage reference expression)이 변수에 의해 구현되는 스토리지 참조에 대해 평가(evaluates)하는 경우, 해당 접근(access)의 공식 접근 기간이 두개의 접근이 모두 읽히지 않은 한, 동일한 변수에 대한 접근 기간과 겹칠 수 있습니다. 


1도 이해가 안가죠? 한마디로 말하면 "접근"은 공식적인 전체 접근 시간동안 독점적이어야 한다는 것이 Law of Exclusivity의 핵심입니다. 


하지만, 우리의 swap...현재 swap의 주된 목적은 mutable collection내에서 두 요소를 "교체"하는 거였습니다. 

하지만 소유권 선언의 일부로 제안된 변경사항들에 따르면, 이것은 더이상 유효한 Swift가 아닙니다. (This will no longer be legal Swift)

단일변수(이 경우 element)는 동일한 함수에 대해 서로 다른 두개의 인수로 전달 될 수 없습니다


아하 이게 핵심이군요. 단일 변수는 동일한 함수에 대해 서로 다른 두개의 인수로 전달 될 수 없다!!!

그러면 swap대신 뭘 써야 하냐 ㅡㅡ



  1. var arr = [1,2,3]

    arr.swapAt(1, 2)//[1,3,2]


swapAt을 씁니다. 그리고 이제는 그 요소 자체를 넘겨주지 않고, 인덱스를 넘겨줍니다!!!


우와아아아앙

그럼 이제 swap안씀..? ㅜㅜ



  1. var name1 = "Zedd"

    var name2 = "Martin"

    swap(&name1, &name2)

    print(name1, name2)//"Martin" "Zedd"


이렇게 쓸 수 있습니다.

제 생각엔 name1과 name2는 동일한 변수가 아니기때문에 접근 기간이 겹칠일이 없어서이지 않을까요? 

위에서 배열같은 경우는 arr라는 하나의 변수에서 element들에 대한 접근들이 겹쳐서 Law of Exclusivity를 위반하는 것 같습니다. 이 자체가 단일변수 2개가 동일한 함수에 전달되는 것이니까요. 



이제 swap(&arr[0], &arr[1])을 할려고 나오는 에러.

overlapping accesses to 'arr', but modification requires exclusive access; consider calling MutableCollection.swapAt(_:_:) 

에 대해서 조금 이해가 가시나요?


arr에 대해 겹친 접근을 하고있습니다.  수정하려면 독점적인 액세스가 필요합니다.  MutableCollection.swapAt(_:_:) 호출을 고려하십시오.


아하

그리고 우리 <Swift로 선택정렬 짜보기>글에서 만났었던 에러..




자기자신과 위치를 교체하는 것은 지원되지 않아서...났던...치명적인....오류..



  1. var arr = [1,2,3]

    arr.swapAt(1, 1)//[1,2,3]



이제 가능~~~~~~XD 


하지만 원래 있던 swap에서는 



  1. var name1 = "Zedd"

    var name2 = "Martin"


    swap(&name1, &name1)//error: inout arguments are not allowed to alias each other


이런 에러가 나니 조심하세요! 


반응형