티스토리 뷰

🍏/Swift

[Swift] Noncopyable (~Copyable)

eungding 2024. 10. 26. 21:20
728x90
반응형

- WWDC 23 > What’s new in Swift : 작년에 소개됨 (Swift 5.9, 제네릭 지원 X) 

- WWDC 24 > Consume noncopyable types in Swift : 올해 별도의 세션이 생김 (Swift 6, 제네릭 지원) 

- SE-0390 Noncopyable structs and enums

 


[1] Noncopyable 

- Noncopyable 은 copy 가 불가능한 타입임을 나타냄  (struct, enum 에서 사용가능) 

- 말할 때는 Noncopyable, code syntax 로는 ~Copyable 

 

- copy 가 불가능하다는 것이 7번 라인이 불가능하다는 뜻이 아니라,

 

 

 

copy 를 한번 하고 나면 ownership이 이전되어서 원본은 못쓰고 복사본만 쓸 수 있다는 의미.

 

 

ㄴ 7번 라인 때문에 user1 은 consume 되었고, ownership 은 user2 에게 넘어감. 8번 라인에서 comsumed 된 user1 에 접근하려고 해서 컴파일에러 발생. 

 

 

 

swift proposal (SE-0390) 에서  noncopyable type 을  move-only type 이라고도 하는데, 

move-only type 이 더 직관적인 용어같음. 

 

 

WWDC 에서는 이런 그림으로 설명함. 

 

 

 

 

 

+ 참고
swift 의 모든 유형은 암묵적으로 Copyable 을 준수함 (직접 작성해줄 필요 X) 

 

 

 

 

[2] Noncopyable > ownership convention

 

ownership convention 으로 consuming, borrowing 를 사용할 수 있음.

 

 

# consuming

 

consuming marking 을 하면 직접 consume 시점을 조정할 수 있음

 

 

ㄴ 11번 라인에서 consuming 메소드가 불려 consume 되었는데, 12번에서 접근해서 컴파일 에러 발생 

 

 

 

ㄴ 7번 라인에서 파라미터 타입이 consuming 인 function 에 넘겨서 consume 되었는데,  8번 라인에서 접근해서 컴파일 에러 발생 

 

 

# borrowing 

 

borrowing 마킹을 해주면 read-only 로 접근가능.

 

 

 

ownership 을 바꾸거나 consume 메소드를 호출하는 것은 안됨. 

 

 

 

참고로 파라미터 타입에는 반드시 ownership 명시를 하도록 컴파일러가 강제하며

디폴트 값은 borrowing. 

 

 

 

inout 관련된 내용은 문서 예제 참고

 

 

[3] Noncopyable > deinit 

 

Noncopyable struct, enum 에는 deinit 을 추가할 수 있음. 

deinit이 불리는 시점은 value 의 lifetime 이 끝나는 시점

 

 

 

헷갈리면 안됨. ownership 이 바뀔 때 불리는게 아님.

 

 

 

또한 consuming method 에 discard self 를 작성하면 deinit 을 호출하지 않고 자신을 파괴함.

 

 

 

 

[3] Noncopyable 필요한 상황 

 

1) 

 

FileDescriptor 는 열려있는 파일을 참조하는 정수를 들고 있어서 이 타입을 복사하면 의도치 않게 mutable 상태를 프로그램 전반에 걸쳐 공유하여 버그를 일으킬 수 있음. 이 구조체의 복사본을 만들 수 없게 하는게 좋음. 

 

 

 

NonCopyable 사용하면 유용. 

 

 

 

다음과 같이 코드 순서를 실수해서 파일을 닫고 쓰는 경우,

런타임 에러가 아니라 컴파일 단에서 에러를 발견할 수 있는 추가 이점도 있음. 

 

 

 

 

2)

 

schedule 메소드에서 transfer.run 이 두번 불릴 수 있는 버그가 있었음.

 

 

 

NonCopyable 사용해서 버그 발견.

 

 

 

return 문 추가해서 두번 호출 방지 하도록 개선.

 

 

 

 

반응형

'🍏 > Swift' 카테고리의 다른 글

[Swift] Typed throws  (0) 2024.10.13
[Swift] AsyncStream  (1) 2024.08.24
[Swift] @TaskLocal  (0) 2024.08.23
[Swift] @dynamicCallable 유용한 예제 모음  (4) 2024.03.16
[Swift] KeyPath 유용한 예제 모음  (32) 2023.10.21
댓글