설명이 부족한 공식 문서 때문에 실무 개발자가 궁금해할... 사실, 내가 궁금했던 내용 중 하나.


https://docs.swift.org/swift-book/ReferenceManual/Patterns.html#grammar_value-binding-pattern

Patterns — The Swift Programming Language (Swift 4.2)

docs.swift.org 


공식문서의 내용에서 쓰는 let point는 튜블 패턴이다.

그런데 튜플은 튜플대로 사용하면 되는데 굳이 switch 문에 다시 바인딩을 시키는 것이 의아하다. 왜냐면 switch 문은 다양한 case에 따라 if 문의 개수를 줄이는데 유용하고 C언어에서 어셈블리로 변화했을 때 switch case문이 다중 if문에 비해 속도가 빠르듯이 더 나은 성능을 위해 switch를 쓰는데 하나의 case문이라면 의미가 없기 때문이다.

인자 개수에 따라 처리가 가능하다면 유용할 텐데 그러지 않다. switch 문의 인자 개수는 동일해야 한다. 만약,


let point = (3, 2, 4)


switch point {

// Bind x and y to the elements of point.

case let (x, y):

print("The point is at (\(x), \(y)).")

case let (x, y, z):

print("The point is at (\(x), \(y), \(z)).")

}


이런 예제라면 에러 난다. 그러면 상수값과 섞어 쓸 때 의미가 있게 된다.



let point = (3, 2)


switch point {
// Bind x and y to the elements of point.

case (3, let y):
print("The point is at \(y).")

case (let x, 2):
print("The point is at \(x).")


default:

print("default")

}






혹은, 

let point = (3, 2)
let point 2 = (3, 8)
let points = (point, point 2)


switch points {

// Bind x and y to the elements of point.

case ((3, 2), let y):

print("The point is at \(y).")

case (let x, (0, 0)):

print("The point is at \(x).")

default:

print("default")

}


이런 식이다. swift는 break문이 필요하지 않아 상위 case에서 참이 되어 버리면 하위 case는 쓸모가 없게 되긴 하지만 튜플 패턴에서 일정 값만 거르고 해당 값을 binding 해서 쓸 때는(굳이 binding 안 하고 써도 되겠지만) 써도 된다는 뜻.


여기서 let을 var로 바꾸었을 때 바딩 된 값이 ref 값인지 copied 값인지 궁금해진다. 


let point = (3, 2)

var point 2 = (3, 8)

let points = (point, point 2)



switch points {

// Bind x and y to the elements of point.

case ((3, 2), var y):

print("The point is at \(y).")

y = (4, 4)

print("The point is at \(y).")

case (let x, (0, 0)):

print("The point is at \(x).")

default:

print("default")

}


print("point 2 = ", point 2)

The point is at (3, 8).

The point is at (4, 4).

point 2 = (3, 8)


복사본이 전달된다. call by reference로 볼 수 있는데 call by assignment 방식 때문에 객체의 경우도 따로 조사를 해봐야 한다. swift에서 class init 후 전달되는 모든 값은 참조형으로 작동하기 때문에라도 한번 더 봐야 한다. 이 말은 3년간 Objective-C 할 때는 함수 포인터보다는 NSNotificationCenter를 통하여 각기 다른 객체(여기서는 파일이라고 생각하면 되겠다)에 메시지를 전달하여 해당 함수를 동작시켰다. 파라미터 전달 방식은 프로그램이 커지고 빌더 패턴이 하나라도 끼인 상태라면 전달이 상당히 복잡해져서 요구사항이 바뀐 경우 그냥 노티피케이션센터에 메시지 하나 더 정의해서 전달했다는 뜻이다. 물론, 안드로이드로 치면 해당 액티비티가 가진 멤버 자료들이 resume 되는 시점에 제대로 복구되는지 상관 않고 기능 구현만 했다는 뜻이다. 대부분 블랙박스 검증이니까 얼추 잘되면 그냥 오케이다. 그러나 의료 앱을 만드는 지금은 웬만한 자료는 가지고 있지 않는다. 함수형 프로그램의 철학대로 데이터의 흐름에만 집중을 한다. 가끔 저렇게 요구사항은 바뀌고 급하게 검증을 돌려야 하는 상황이면, Call by Reference를 십 분 활용하여



var pDashboard : DashboardScrollView? = nil




이렇게 꼭 필요한 자료가 있는 싱글톤에 정의하고, 



GS.s.pDashboard = self



만든 객체를 넣고



GS.s.pDashboard?. topScroll()



어디서든 호출할 수 있게 한다. 참고로 swift에서 싱글톤은

private init()

static let s


으로 만든다. 사실, 나의 실무 프로그래밍 책에 쓴 것럼 동시성을 체크해야 하지만 네트워크 상황에서도 DispatchQueue 를 전혀 쓰지 않고 있기 때문에 문제는 없어 보인다. closure를 이용하면 된다. (더블클로저를 이용한 프로그래스바 참조) 물론, 운영체제 혹은 프로세서의 멀티 프로세싱에서 앱이 따로 thread를 만들지 않으면 앱 실행 순서는 리니어 하다는 것을 가정해야 하는 위험이 있긴 하지만 다른 안정 장치로 의료용 앱을 보호해야 한다.


자 다시, call by assignment 로 돌아가자. 튜플은 값을 주고, 튜플도 객체니 그냥 call by reference로 믿어도 되겠지만 결국 책임은 실무 프로그래머에게 있으니 의심해 볼 수 밖에 없다.


class dummy {

var A : Int = 3

}


더미 class를 만들자.


var a = dummy()



switch a {

case var b :

print("a.A = \(a.A)")

print("b.A = \(b.A)")

b.A = 2

print("a.A = \(a.A)")

print("b.A = \(b.A)")

default:

print("defult")

}


print("a.A = \(a.A)")


a.A = 3

b.A = 3

a.A = 2

b.A = 2

a.A = 2



바뀐다. 그럼 이 경우는?



var a = dummy()



switch a.A {

case var b :

print("a.A = \(a.A)")

print("b = \(b)")

b = 2

print("a.A = \(a.A)")

print("b = \(b)")

default:

print("defult")

}


print("a.A = \(a.A)")



a.A = 3

b = 3

a.A = 3

b = 2

a.A = 3


안바뀐다.


결국, 파이썬처럼 call-by-assignment 로 동작하는 것을 볼 수 있다.



이제 switch 바인딩의 의미가 값 결정에 있지 않고 단순 커넥션이며, 객체에 따라 다르게 assignment로 동작한다는 것을 알 수 있다. swift는 직관적 리딩을 위해 파라미터 까지도 생략하려면 _(under score)를 써야 하게 해놨는데 복잡하게 프로그래밍 하는 것보다는 직관적으로 알 수 있게 하는게 나을 것이다.


그러나, 난 어렵게 프로그래밍 하는 것을 추천한다. 거대한 switch 문을 만들길 바란다. 대한민국은 프로그래머보다 경영자가 우대받는 사회니까. 우리팀이 이기길 바라는 것은 팀원으로 당연한거니까.



띄워쓰기가 맘에 안들수도 있겠다. 귀차니즘에 의해 Xcode의 ^I 정렬 방식을 따르고 브런치의 맞춤법 검사를 필터링 없이 돌린다.(소스에도 걸리는 것을 보니 ...)



혹 구독자를 위해 요약하면,




Swift의 value-binding pattern은 call by assignment 로 동작한다는 것. 물론, siwft 4.2 기준이며 5가 되었을 때도 공식문서에 별다른 말이 없으면 다시 확인해야 한다. product랑 가까운 개발자 일수록 이런 말 못할 고민은 늘어간다. 비트 하나 차이로 사람이 죽을수도 있으니... 늘 낮은 자세로 탐구하고 고민하고 책임져야 한다. ㅠㅠ 

요약 1
이 글은 Swift의 switch문에서 사용되는 value-binding pattern에 대해 설명하고 있습니다.

주요 내용은 다음과 같습니다:

1. Swift 공식 문서에서 설명하는 value-binding pattern은 튜플 패턴을 사용하며, switch문에서 바인딩을 할 때 사용됩니다.

2. switch문의 case에서 상수값과 섞어 사용할 때 의미가 있으며, let을 var로 바꾸었을 때 바인딩된 값이 참조값인지 복사값인지 궁금해집니다.

3. 실험 결과, value-binding pattern에서 바인딩된 값은 복사본이 전달되며, call by reference로 볼 수 있지만 실제로는 call by assignment 방식으로 동작합니다.

4. Swift에서 클래스 초기화 후 전달되는 값은 참조형으로 작동하므로, 객체의 경우도 따로 조사해봐야 합니다.

5. 실무에서는 요구사항 변경에 따라 싱글톤 패턴과 Call by Reference를 활용하여 유연하게 대응할 수 있습니다.

6. Swift의 value-binding pattern은 call by assignment로 동작하며, 객체에 따라 다르게 할당됩니다.

7. 의료 앱 개발과 같이 중요한 분야에서는 비트 하나의 차이로 인해 큰 문제가 발생할 수 있으므로, 늘 책임감을 가지고 탐구하고 고민해야 합니다.

요약2; 요약하자면, Swift 문서에서 설명하는 value-binding pattern은 call-by-assignment 방식으로 동작한다는 것입니다. 이는 switch 문에서 let 또는 var를 사용하여 튜플 패턴을 바인딩할 때, 값이 복사되어 전달됨을 의미합니다. 예제에서는 튜플 패턴의 사용과 switch 문에서의 바인딩을 통한 값 할당 방식을 보여주며, 이를 통해 Swift에서 값의 전달이 어떻게 이루어지는지를 설명합니다. 특히, 클래스 인스턴스와 같이 참조 타입의 경우에도 바인딩된 변수가 복사가 아닌 참조를 통해 값을 전달받는지, 아니면 복사를 통해 전달받는지에 대한 궁금증을 제시합니다. 또한, 이러한 동작 방식이 Swift의 버전에 따라 달라질 수 있으므로, 공식 문서를 통해 최신 정보를 확인해야 함을 강조합니다. 실무 개발자로서는 이러한 세부적인 동작 방식의 이해가 중요하며, 프로그램의 정확성과 효율성을 높이기 위해 깊이 있는 탐구와 고민이 필요함을 언급합니다.

선배님

이 한 분 계신다. 고마운 분이야 정말 많지만 가깝게 지내는 선배님은 딱 한 분이다. 각자 좋아하는 선배가 학교에 있는 이유는 다양하겠다. 나의 경우엔

 

- 10년이 넘도록 변함없이 한결같은 모습을 보여주시고,

- 쉼 없이 자기 일을 하며,

- 직장인이지만 정의 구현을 위해 당연히 해야 할 말을 늘 말하고,

- 적이 생기는 글을 SNS에 공개할 정도로 다른 사람 도움 없이 능력은 인정받고 있으며,

- 단, 한 번도 후배에게 밥을 얻어먹은 적이 없다.

 

보통 친구를 만나도 본인이 사는 것이라면 값싼 곳을 찾기 마련이고. 오히려 형들에게 내가 밥을 더 사주고 몇 번 얻어먹은 것으로 본인들은 자신들이 다 샀다며 기억 조작하기 일쑤다. 뭐라 형용할 수 없을 정도로 많은 케이스가 있다는 것을 말하고 싶다. 그리고 난 술을 마셔도 서로 돈이 없으면 편의점 가서 맥주 한 캔을 따도, 혹은 놀이터 가서 하염없이 이야기해도 좋은 친구들이 있다. 좋은 사람을 보는데 굳이 누가 뭘 사는 것이 중요한 것은 아니지만 선배님이 재벌은 아니므로, 수많은 후배들 자주 밥 사 주는 것은 분명 부담이라는 것을 안다. 그러나 그만큼 관계를 더 중요시한다는 말도 되겠다. 나는 이렇게 해 주는 후배는 없고, 제자는 있다.

 

그러나 옛날 사람인 선배님의 철학은 간단하다. 후배가 밥을 얻어먹냐고. 그래서 일부러 싼 곳을 찾지만 늘 당신이 먹었던 식당 중 최고의 식당을 찾고 그래서 가격도 만만치 않다. 물욕은 또 없으셔서 선물도 잘 받지 않는데, 기습적으로 드리지 않으면 선물을 줄 기회도 잘 없다.

 

 

 

+ Recent posts