swift에서의 struct와 class의 개념적 차이에 대하여 (기능적 차이가 아님!)

학교에서 컴퓨터 구조 강의시간에 객체지향프로그래밍 패러다임에서 클래스가 등장했다고 배웠습니다.

그 이유가 이전의 절차지향프로그래밍 패러다임에서는 라이브러리를 통해 현실의 개념을 코드를 통해 **추상화(modeling)**하기가 어려웠기 때문이라고 들었습니다.

이로 미루어보아 클래스라는 문법의 등장 배경은 "현실의 개념을 보다 쉽게 코드로 표현하기 위함"이라고 생각할 수 있을 것 같습니다.

swift에서의 struct와 class의 차이점에 대해 조사를 하던 중 인터넷의 대부분의 설명은 기능적 차이(값 복사 혹은 레퍼런스냐 등) 에 초점을 맞추고있어 개념적 차이에 대해 궁금해졌습니다.

C와 같은 언어에서는 struct 문법의 존재 의의는 “값을 모아두기 위함”, "데이터의 묶음"이라고 합니다.

swift에서의 class 문법의 존재의의와 struct 문법의 존재의의에 대해 알고 싶습니다.
struct는 값을 복사한다, class는 하나의 object를 referencing해서 사용한다. 와 같은 기능적 차이 등에 대해서 여쭙고 싶은 것이 아닙니다.

C의 struct과 비교하자니 **“값을 모아둔다”**라고 설명하기에는 아닌 것 같고
OOP개념에서의 Class와 비교하자니 현실의 개념을 모델링한다는 점에서는 차이가 별로 없어보입니다.

감사합니다.

좋아요 3

구조체나 클래스를 모두 [값을 모아두는 의미]로만 보면 차이가 없어 보입니다.

"새로운 타입"을 정의하는 것이라고 보면 차이가 발생합니다.

클래스는 구조체와 다르게 상속이 가능하므로 타입 간 is-a 관계가 발생합니다.

다음 클래스 상속 관계에서 Actor 클래스의 객체는 Person 으로 다룰 수 있습니다.

class Person {}
class Actor: Person {}

구조체는 이런 객체 간의 관계가 불가능합니다.

좋아요 4

클래스에서는 “새로운 타입을 정의한다” 라는 의미가 추가되니

말씀해주신 내용을 바탕으로 생각해보면

< 나는 **“새로운 타입(현실의 모델)”**을 정의하고 싶어 > 라는 의도를 가지고 코드를 작성할 때는 class를 사용하는 것이 보다 자연스러운 선택이고

< 나는 **“새로운 타입(현실의 모델)”**을 정의하고 싶은 건 아니지만 값을 모아둘 어떤 형식이 필요해 > 라는 의도를 가지고 코드를 작성하면 struct를 사용하는 것이 자연스러운 선택이 되는 건가요?

답변 감사드립니다.

좋아요 1

구조체도 충분히 새로운 타입을 정의하는 용도로 사용합니다.

실제로 Swift의 많은 타입이 구조체로 되어 있습니다.

https://developer.apple.com/documentation/swift

좋아요 2

“나는 10진수 정수를 사용하고 싶어” 라는 의도 → Int 사용
“나는 문자열을 사용하고 싶어” 라는 의도 → String 사용
“나는 여러 데이터를 묶어서 사용하고 싶어” 라는 의도 → Array사용
“나는 ???를 위해 사용하고 싶어” 라는 의도 → stuct 사용
“나는 ???를 위해 사용하고 싶어” 라는 의도 → class 사용

저는 이 ???에 들어가는 답을 얻고 싶었습니다 ㅠㅠㅠ

클래스는 구조체와 다르게 상속이 가능하다는 것, 하나의 값을 레퍼런스해서 사용한다는 것 등 기능적 차이는 잘 알겠으나…
우리 프로그래머 입장에서 어떤 개념을 (그 문법이 등장한 배경을) 바탕으로 의도를 가지고 써야하는데
그 의도가 기능적 차이에 의해 결정되면 시원하지 않다…랄까… 어쨌든 그렇습니다… ㅠㅠㅠㅠㅠ

제가 너무 어렵게 생각하는 것인지 모르겠습니다만 계속해서 관련 정보를 찾던 중 애플 공식 문서에서 제가 질문한 부분에 대해 어느정도 답변이 되는 부분을 찾았습니다.

https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes#see-also

애플 공식 가이드 문서에서도 언제 스트럭트를 쓰고 클래스를 써야하는가? 에 대한 문제에 대해 얘기하고 있습니다.
대신 struct와 class 문법 등장 배경에 근거하여 의미론적으로 풀기보다는 다른 기술 블로그들 처럼 기능적인 차이 측면에서 풀어쓰고 있어서 정말 정확히 제가 원했던 부분은 아니지만… 공식 가이드북에서도 이정도로 얘기하니 그냥 받아들여야 하지 않을까 합니다.

어떤 문법이 어떤 부족한 점을 보완하기 위해 등장했는지 안다면 (ex 반복된 값을 잘 관리하기 위해 배열이 등장, 같은 코드블록의 반복을 줄이기 위해 함수 등장), 적재 적소에 그 부족한 점이 보일 때 적용시켜 사용할텐데… 이 struct와 class의 배경은… ㅠㅠㅠㅠ 얘들은 참 어려운 친구들 같습니다.

답변 감사드립니다.

좋아요 2

기능 상의 차이를 빼고 의미 상의 차이로만 타입을 선택하는 것은 불가능하다고 생각합니다. 기능 상의 차이로 더 유리한 방식을 선택하는 경우가 꽤 많습니다.

JSON으로 문자열 타입으로 된 날짜 정보가 오면 어떻게 해야 할까요? Date 타입으로 할까요? 아니면 문자열 타입으로 다뤄야 할까요? 단순히 데이터를 그대로 출력하는 상황이라면 문자열로 다루는 것이 더 유리하죠.

그런데 날짜를 다른 포맷으로 변환해야 하는 상황이 있거나 시차를 고려해야 하는 상황이라면 Date 타입을 쓰는 것이 유리하죠.

기능과 의미를 모두 생각해서 더 상황에 유리한 방식을 찾는게 더 좋지 않은가 생각합니다.

그런 의미에서 기능상 차이로 구조체와 클래스를 고르지 못하면 일단 구조체로 시작해보라고 애플에서 가이드를 주고 있습니다.

좋아요 4

이해되었습니다. 편협한 사고에서 벗어날 수 있는 계기가 되었던것 같습니다. 감사합니다!

좋아요 2

사족이 될지 모르겠지만, 첨언을 하자면,

Struct은 그동안 Value 타입이라 외면 받아온 모델입니다. 메모리 낭비가 심하기 때문에 C 에서는 좌표계를 담는 등 가벼운 데이터를 다루는 용도로만 사용했지, 그 안에 구조를 넣고 메소드를 잔뜩 구현해서 하나의 모델로서 활용할 생각을 하지 않아온 방식이죠.

Class 는 OOP 와 함께 등장해서 많은 문제들을 해결했죠. 메모리 번지를 참조하는 방식으로 인해 하나의 오브젝트를 다양한 곳에서 주소값만 넘겨서 활용할 수 있었고, 무엇보다 '상속’이라는 기능을 이용해 체계적으로 속성과 기능을 정리해서 큰 규모의 코드를 작성할 때 유리한 점이 많았어요.

하지만, 시대가 변해서 메모리 공간을 절약할 수 있는 Ref 타입이라는 게 오히려 크래시를 일으키는 이유가 되고 충분한 메모리 공간을 분리 활용해서 코어의 성능을 극대화할 수 있다면 그게 더 장점으로 인정받게 되면서 Value 타입인 Struct 가 재조명 받게 되었습니다.

다만, Stuct은 Class 처럼 상속을 할 수가 없는 게 치명적인 단점인데요, 그런 상속에 대한 필요성을 Protocol을 이용해 해결해 낸 프로그래밍 패러다임이 POP (Protocol Oriented Programming) 인 거죠.

프로토콜은 상속이 되니까, 상속해야 하는 복잡한 속성이나 기능들을 프로토콜로 외부에 정의해 두고, 그걸 상속 체계 안에서 확장하면서 관리하고, Struct은 적절한 단계의 Protocol 을 준수하는 것으로 원하는 수준의 기능을 얻도록 하는 거죠.

이게 UIKit 은 OOP 패러다임으로 만들어진 프레임워크이다보니, 그걸 완전히 Struct 기반의 POP 패러다임으로 다시 작성한게 SwiftUI 인 거구요.

완전한 POP 전환이 꽤나 시간이 많이 걸릴 것으로 예상했는데, SwiftUI 가 생각보다 빠르게 자리를 잡아가는 걸 보면, 애플이 준비를 오랫동안 한 건지, 애플이 포획한 외계인들이 그만큼 많은건지… 암튼 대단하네요. 애플.

이로서 SwiftUI는 단지 ‘MVVM을 구현한 UI 프레임워크들 중 하나’ 가 아니라 POP를 완벽하게 구현해 낸 첫번째 UI 프레임워크로서 큰 의미를 가진다고 볼 수 있습니다.

좋아요 4

아하! 그런 배경이 숨어있었군요… ㅎㅎㅎㅎ

이제 왜 Struct를 사용하는지, 언제, 어느 용도로 Struct와 Class를 사용해야 할지에 대해 감이 잡힌 것 같습니다.

그리고 저도 따로 POP 패러다임에 대해 더 조사를 해볼 필요가 있어보이네요.

이렇게 그 문법을 왜 사용하는지에 대해 알면 더 좋은 코드를 짤 수 있을 거란 개인적 믿음(?)이 존재하기에, 계속 관련 정보를 찾아보고 있었는데…

자세한 답변 달아주셔서 감사합니다!

좋아요 2