글 작성자: HEROHJK

C++에서는 구조체와 클래스의 차이가 거의 없습니다.


구조체는 기본값이 public, 클래스는 기본값이 private인것 외에 차이는 거의 없다고 들었습니다.


그래서 보통 개념적으로만 구분을 했었죠. 클래스는 정말 객체지향의 의미로 하나의 객체의 요구사항들을 정의할때 이용하는것이었고, 구조체는 단순한 값들의 묶음(레코드?)을 이용할때만요(틀릴수도 있겠지만 개인적으론 그렇게 이용했습니다)


하지만 스위프트에서는 조금 다릅니다.


대표적으로 스위프트에서의 클래스는 참조, 구조체는 복사의 의미를 가지고 있습니다.


스위프트 클래스A를 B로 가져오면, B=A가 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public Class MyClass{
    public var integer: Int = 0
    public var string: String = ""
}
 
var A: MyClass = MyClass()
 
A.string = "HEROHJK"
A.integer = 10
 
print(A.string)        //HEROHJK 출력
print(A.integer)    //10 출력
 
var B = A
 
print(B.string)        //HEROHJK 출력
print(B.integer)    //10 출력
 
B.string = "KJHOREH"
B.integer = 99
 
print(B.string)        //KJHOREH 출력
print(B.integer)    //99 출력
 
print(A.string)        //KJHOREH 출력
print(A.integer)    //99 출력
cs


결과가 다음처럼 출력이 됩니다.


그 외 부분은 조금 더 나중에 공유 하도록 하겠습니다.


그래서 어제 만들었던 스택을 구조체로 변경해 보았습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import Swift
 
public struct Stack<T>{
    private var stack = [T]()       //배열로 이루어져 있다.
    private var length: Int = 0     //길이
    
    //선언과 동시에 스택 초기화
    public init (){
        stack.removeAll(keepingCapacity: false)
        length=0
    }
    
    //스택 값 삽입
    public mutating func Push(_ object: T) -> Int{
        //0번째에 값을 삽입한다
        stack.insert(object, at: 0)
        //스택의 길이를 늘린다
        length=length+1
        
        return stack.count
    }
    
    //스택 값 추출
    public mutating func Pop() -> T{
        
        //처음 값을 불러온다
        let object=stack[0]
        //처음 값을 삭제한다
        stack.remove(at: 0)
        //길이를 줄인다
        length=length-1
        
        
        return object
    }
    
    //스택 초기화
    public mutating func Clear()->Int{
        //스택을 비운다
        stack.removeAll(keepingCapacity: false)
        //길이를 0으로 초기화한다
        length=0
 
        //길이 값 반환
        return length
    }
    
    //스택이 비어있는지 확인
    public var IsEmpty: Bool{
        //0보다 많으면 거짓을 반환
        
        if(length>0){
            return false
        }
        
        //아니면 참을 반환
        return true
    }
    
    //스택 길이 확인
    public var GetLength: Int{
        return stack.count
    }
    
}
//여기부터는 테스트용 코드입니다
var stack: Stack<Int> = Stack<Int>()
 
var count: Int=1
while count<=100{
    stack.Push(count)
    count=count+1
}
 
while stack.IsEmpty==false{
    print(stack.Pop())
}
cs


크게 바뀐부분은 없는것 같습니다.


다만 일부함수(삽입/추출/초기화)에 퍼블릭 옆에 mutating 이라는 키워드가 들어가있죠?


mutating을 사용하는이유는 다음과 같이 나옵니다.


"스위프트에서 구조체와 열거형은 Value Type이기 때문에 생성된 객체의 메소드 안에서 해당 Value Type의 속성값을 바꿀 수 없습니다.그래서 나타난 스위프트 핵심어 Mutating 을 알아보겠습니다.

이런 전제하에서 스위프트 Mutating 핵심어는 해당 Value Type 내의 메소드가 속성값을 바꿀 수 있도록 만듭니다."

(출처 : http://imackorea.com/2015/07/%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8-%ED%95%B5%EC%8B%AC%EC%96%B4-mutating/)


이는 c#과도 비슷합니다.(다른언어들은 안해봐서 잘 모르겠네요) 한번 생성되면 밸류타입으로 생성이되어서 레퍼런스(참조)타입으로 생성이되는 클래스와는 다르게 정상적으로 바꾸기가 쉽지 않죠..

따라서 삽입/추출/초기화부분에만 mutating키워드가 붙어있는것 입니다.

반응형