Class vs Struct/Enum

소스코드


열거형과 구조체는 값 타입이며, 클래스는 참조 타입이라는 것이 가장 큰 차이입니다. 또한, 클래스는 상속이 가능하지만 구조체와 열거형은 상속이 불가능합니다.

struct ValueType {
    var property = 1
}

class ReferenceType {
    var property = 1
}

// 첫 번째 구조체 인스턴스
let firstStructInstance = ValueType()
// 두 번째 구조체 인스턴스에 첫 번째 인스턴스 값 복사
var secondStructInstance = firstStructInstance
// 두 번째 구조체 인스턴스 프로퍼티 값 수정
secondStructInstance.property = 2

// 두 번째 구조체 인스턴스는 첫 번째 구조체를 똑같이 복사한 
// 별도의 인스턴스이기 때문에 
// 두 번째 구조체 인스턴스의 프로퍼티 값을 변경해도
// 첫 번째 구조체 인스턴스의 프로퍼티 값에는 영향이 없음
print("first struct instance property : \(firstStructInstance.property)")    // 1
print("second struct instance property : \(secondStructInstance.property)")  // 2


// 클래스 인스턴스 생성 후 첫 번째 참조 생성
let firstClassReference = ReferenceType()
// 두 번째 참조 변수에 첫 번째 참조 할당
let secondClassReference = firstClassReference
secondClassReference.property = 2

// 두 번째 클래스 참조는 첫 번째 클래스 인스턴스를 참조하기 때문에
// 두 번째 참조를 통해 인스턴스의 프로퍼티 값을 변경하면
// 첫 번째 클래스 인스턴스의 프로퍼티 값을 변경하게 됨
print("first class reference property : \(firstClassReference.property)")    // 2
print("second class reference property : \(secondClassReference.property)")  // 2


관련문서

The Swift Programming Language - Enumerations

The Swift Programming Language - Classes and Structures





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 


저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

프로퍼티 - Property  (2) 2017.06.26
클로저 - Closure  (0) 2017.06.22
클래스, 구조체, 열거형 비교  (0) 2017.06.19
열거형 - Enumerations  (0) 2017.06.15
클래스  (0) 2017.06.12
구조체  (2) 2017.06.08
Posted by yagom

구조체

Swift/기본문법 2017.06.08 11:00

구조체


소스코드



정의 문법

스위프트 대부분의 타입은 구조체로 이루어져 있습니다.
구조체는 값 타입입니다.
타입이름은 대문자 카멜케이스를 사용하여 정의합니다.

struct 이름 {
	/* 구현부 */
}


프로퍼티 및 메서드 구현

struct Sample {
	// 가변 프로퍼티
    var mutableProperty: Int = 100 
    
    // 불변 프로퍼티
    let immutableProperty: Int = 100 
    
    // 타입 프로퍼티
    static var typeProperty: Int = 100 
    
    // 인스턴스 메서드
    func instanceMethod() {
        print("instance method")
    }
    
    // 타입 메서드
    static func typeMethod() {
        print("type method")
    }
}


구조체 사용

// 가변 인스턴스 생성
var mutable: Sample = Sample()

mutable.mutableProperty = 200

// 불변 프로퍼티는 인스턴스 생성 후 수정할 수 없습니다
// 컴파일 오류 발생
//mutable.immutableProperty = 200

// 불변 인스턴스
let immutable: Sample = Sample()

// 불변 인스턴스는 아무리 가변 프로퍼티라도
// 인스턴스 생성 후에 수정할 수 없습니다
// 컴파일 오류 발생
//immutable.mutableProperty = 200
//immutable.immutableProperty = 200


// 타입 프로퍼티 및 메서드
Sample.typeProperty = 300
Sample.typeMethod() // type method

// 인스턴스에서는 타입 프로퍼티나 타입 메서드를
// 사용할 수 없습니다
// 컴파일 오류 발생
//mutable.typeProperty = 400
//mutable.typeMethod()


학생 구조체 만들어보기

struct Student {
	// 가변 프로퍼티
    var name: String = "unknown"

    // 키워드도 `로 묶어주면 이름으로 사용할 수 있습니다
    var `class`: String = "Swift"
    
    // 타입 메서드
    static func selfIntroduce() {
        print("학생타입입니다")
    }
    
    // 인스턴스 메서드
    // self는 인스턴스 자신을 지칭하며, 몇몇 경우를 제외하고 사용은 선택사항입니다
    func selfIntroduce() {
        print("저는 \(self.class)반 \(name)입니다")
    }
}

// 타입 메서드 사용
Student.selfIntroduce() // 학생타입입니다

// 가변 인스턴스 생성
var yagom: Student = Student()
yagom.name = "yagom"
yagom.class = "스위프트"
yagom.selfIntroduce()   // 저는 스위프트반 yagom입니다

// 불변 인스턴스 생성
let jina: Student = Student()

// 불변 인스턴스이므로 프로퍼티 값 변경 불가
// 컴파일 오류 발생
//jina.name = "jina"
jina.selfIntroduce() // 저는 Swift반 unknown입니다


관련문서

The Swift Programming Language - Classes and Structures





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 

저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

열거형 - Enumerations  (0) 2017.06.15
클래스  (0) 2017.06.12
구조체  (2) 2017.06.08
옵셔널  (0) 2017.06.05
반복문  (0) 2017.06.01
조건문  (0) 2017.05.29
Posted by yagom


오늘의 주제

Objective-C의 상수와 스위프트의 상수


안녕하세요 야곰입니다.

Objective-C를 쓰다가 스위프트로 넘어왔을 때 고민되었던 부분 중의 하나인 스위프트의 상수에 관해 이야기해 보려 합니다.


혼자 프로젝트를 진행하다 보면 상수의 필요성을 많이 느낄 수 없을지 모르지만, 누군가 협업을 하게 된다면, 혹은 미래 또는 과거의 나와 협업(?)을 하게 된다면 상수의 필요성을 많이 느끼게 됩니다. 바꾸면 안 되는 데이터를 실수로 바꿔서 난감했던 경험이 없나요? 혹시 그런 적이 있다면 상수의 필요성에 대해서는 많이 공감하실 것으로 생각됩니다.


* 오해가 생길 소지의 표현들이 있어서 처음 발행 이후 조금 수정하였습니다. 좋은 의견 주신 과니님 고맙습니다 :)


사라진 const


사실 저는 Objective-C에서 특별한 경우가 아니면 const를 많이 사용하지 않았습니다(반성).


그런데 스위프트에서는 전역이든 지역이든 데이터를 저장할 공간(변수 또는 상수)에는 var 또는 let을 사용하여 변수인지 상수인지 명확히 명시해 주어야 하므로 상수에 대한 고민을 많이 하게 되었습니다.


사실 지역상수가 필요한 경우에 const 키워드를 쓰는 귀찮음 때문에 상수를 많이 사용하지 않았는데 스위프트에서는 var 또는 let을 선택해야 하는 시간이 조금 걸렸지만, 지금은 큰 시간 들일 필요 없이 자연스럽게 상수를 많이 사용하고 있습니다. 또, 혹시라도 상수로 사용해야 하는 경우임에도 변수로 선언하고 사용한다면 Xcode에서 변수 대신 상수를 사용하는 게 어떻냐는 경고를 보여줍니다. 




[Xcode의 경고]


지역상수


지역상수를 사용하는 경우에는 사실 Objective-C와 크게 다를 바 없이 사용할 수 있습니다. 상수의 이름을 지어주는 명명법도 크게 다를 바 없습니다. 

상수로 사용할 변수 앞에 const를 붙여 쓴 것처럼 let을 사용하여 상수를 선언하여 사용하면 됩니다.



// Objective-C
const NSInteger someConstant = 100;


// Swift
let someConstant: Int = 100



전역상수


전역상수를 사용할 때 조금 더 생각해보아야 할 것들이 있습니다. 저는 처음 스위프트를 사용할 때 별생각 없이 Objective-C에서 사용하던 것과 같은 명명법으로 전역상수를 사용했습니다.


// Objective-C NSInteger const  YGSomeGlobalConstant = 100;


// Swift
let YGSomeGlobalConstant: Int = 100


그런데 Objective-C에서 'YG'와 같이 접두어(prefix)를 붙이는 것은 Objective-C에는 네임스페이스(name space)가 없기 때문인데, 스위프트에는 이 단점을 극복했다는 것에 대한 생각이 문득 스쳤습니다.


Objective-C에는 네임스페이스가 없어서 전역변수를 선언하고 사용할 때 꽤 골치가 아팠습니다. 귀찮기도 아주 귀찮았죠. 이름도 매우 길어지기만 했습니다. 열거형(enum)은 정수밖에 지원하지 않기 때문에 다른 타입의 값들은 관련된 상수끼리 묶어 쓰기도 어렵기도 했지요.


// Objective-C의 상수들... // 네임스페이스가 없기 때문에 // 연관된 상수들을 접두어를 사용하여 표현합니다 // 요일 상수들 NSString *const YGWeekMonday = @"MON"; NSString *const YGWeekTuesday = @"TUE"; NSString *const YGWeekWednesday = @"WED"; NSString *const YGWeekThursday = @"THU"; NSString *const YGWeekFriday = @"FRI"; NSString *const YGWeekSaturday = @"SAT"; NSString *const YGWeekSunday = @"SUN"; // 네트워킹 관련 상수들 NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";


정말 보기만 해도 정신이 없습니다. 또, 실수로 복사 붙여넣기를 하다가 중복된 값을 넣었다면 컴파일 오류가 발생하지 않기 때문에 실수를 찾아내기도 매우 어려워집니다.


스위프트에서는 이런 전역 상수들을 조금 더 멋진 방법으로 표현해 볼 수 있습니다. 타입 내부에 다른 타입을 정의하는 방법으로 네임스페이스를 사용할 수 있습니다. 더군다나 네임스페이스 덕분에 접두어는 더 이상 스위프트에서 사용하지 않습니다.


// Week라는 구조체 타입 내부에
// 여러 타입 상수를 선언
struct Week {
    static let mon: String = "MON"
    static let tue: String = "TUE"
    static let wed: String = "WED"
    static let thu: String = "THU"
    static let fri: String = "FRI"
    static let sat: String = "SAT"
    static let sun: String = "SUN"
}

// 실제 사용시 Week.mon // "MON" Week.sat // "SAT"


처음에 이렇게 선언해 보았습니다. 그런데 만약 복사 붙여넣기를 하다가 실수로 중복된 값을 넣는다면...? 가령 "SUN"을 넣어야 하는데 "SAT"를 넣어버렸다면? 이때는 중복 값이 들어있는지 확인할 수 없습니다. 물론 의도적으로 다른 이름의 상수에 같은 값을 넣을 수도 있지만 그렇지 않은 경우에는 낭패입니다.


그래서 이렇게 개선해 봅니다.


// 열거형의 연관 값(associated value)을 사용하여
// 상수처럼 사용
enum Week: String {
    case mon = "MON"
    case tue = "TUE"
    case wed = "WED"
    case thu = "THU"
    case fri = "FRI"
    case sat = "SAT"
    case sun = "SUN"
}

// 실제 사용시 Week.mon.rawValue // "MON" Week.sat.rawValue // "SAT"



이렇게 사용하면 열거형 내부의 연관 값이 중복되는 경우에 컴파일오류가 발생하게 됩니다. 그래서 미리 실수를 발견하기도 좋습니다.


또, 위의 Objective-C로 선언했던 네트워킹 관련 상수를 스위프트에서 선언한다면 이렇게 바꿔볼 수 있을 것 같습니다.


// Objective-C NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";
// 사용 YGNetworkingTimeoutInterval // 10.0


// Swift
struct Networking {
    static let timeoutInterval: TimeInterval = 10.0
    static let maxRetryCount: Int = 3
    static let baseURL: URL? = URL(string: "https://abc.com")
}

// 사용

Networking.timeoutInterval // 10.0


이처럼 꼭 열거형의 연관 값을 사용하지 않고 용도에 맞게 구조체의 타입 상수(static let)로 사용해도 좋습니다. 


상수뿐만 아니라 전역변수, 전역함수(메서드) 등에도 충분히 응용할 수 있습니다.


또한 구조체 내부에 다른 타입(구조체, 클래스, 열거형) 등등 몇 단계를 걸쳐 내부 타입을 정의할 수 있기 때문 연관된 값을 타입의 타입의 타입까지 여러 번에 걸쳐 정의도 가능합니다.



struct CalendarItem {
    typealias Year = Int
    typealias Day = Int
    
    enum Week: String {
        case mon = "MON", tue = "TUE" //...
    }
    
    enum Month: Int {
        case jan = 1, feb, mar //...
    }
    
    static let startYear: Int = 1970
    static let startMonth: CalendarItem.Month = .jan
    
    struct Date {
        var day: Day = 1
        var weekDay: CalendarItem.Week = .mon
        var month: CalendarItem.Month = .jan
        var year: Year = CalendarItem.startYear
    }
}

var userBirthday: CalendarItem.Date userBirthday = CalendarItem.Date.init(day: 10, weekDay: .tue, month: .mar, year: 2017)



마치며


같은 Cocoa 플랫폼 위에서 코드를 작성하는데도 불구하고 역시나 언어의 특성을 살려 새로이 구조를 설계하기는 쉽지 않습니다 하핳


무언가 두서없이 써내려간 느낌입니다만, 잘 이해가 가지 않거나 궁금한 점이 있다면 댓글 남겨주세요 :D





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


저작자 표시 비영리 변경 금지
신고
Posted by yagom


오늘의 주제

1. 구조체
2. 클래스



안녕하세요, 야곰입니다. 


지난 포스팅에서는 스위프트의 함수와 함께 스위프트에서 제공하는 컬렉션 타입에 대해 알아봤습니다.


2017/01/23 - [Swift] - Swift란 어떤 언어인가?

2017/01/25 - [Swift] - Swift 기초문법 - 변수, 상수, 기초 데이터 타입

2017/02/06 - [Swift] - Swift - 함수, 콜렉션 타입



이번에는 스위프트의 구조체와 클래스에 대해 알아보겠습니다 :)


구조체와 클래스

구조체와 클래스는 프로그래머가 데이터를 용도에 맞게 묶어 표현하고자 할 때 용이합니다. 구조체와 클래스는 프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가질 수 있습니다. 하나의 새로운 사용자정의 데이터 타입을 만들어 주는 것입니다. 


객체지향 프로그래밍 패러다임을 알고 있다면 클래스라는 용어를 들어봤을 겁니다. 객체지향 프로그래밍 패러다임이 아니더라도 데이터를 구조화하여 관리하는 데 구조체를 사용해봤을 겁니다. 스위프트에서는 구조체와 클래스의 모습과 문법이 거의 흡사합니다. 다만, 구조체의 인스턴스는 값 타입이고, 클래스의 인스턴스는 참조 타입이라는 것이 이 둘을 구분하는 가장 큰 차이점입니다. 


이제까지 우리가 알아본 스위프트의 데이터 타입과 열거형은 모두 값 타입니다. 그러나 구조체와 함께 배워볼 클래스는 참조 타입입니다. C 언어와 Objective-C의 포인터와 유사한 개념입니다. 


참고로 스위프트는 참조 타입보다는 값 타입에 친절한 언어입니다.



구조체


구조체는 struct 키워드로 정의합니다.


구조체 명명법



struct [구조체 이름] { [프로퍼티와 메서드들] }


아래에 사람의 기본 정보를 구성하는 구조체를 정의해봤습니다. BasicInformation 이라는 이름으로 정의했으며 이 구조체는 String 타입인 name과 Int 타입인 age라는 저장 프로퍼티를 가집니다.

struct BasicInformation {
    var name: String
    var age: Int
}


구조체 인스턴스의 생성 및 초기화


구조체 정의를 마친 후, 구조체의 인스턴스를 생성하고 초기화하고자 할 때에는 기본적으로 생성되는 멤버와이즈 이니셜라이저를 사용합니다. 구조체에 기본 생성된 이니셜라이저의 매개변수는 구조체의 프로퍼티 이름으로 자동 지정됩니다. 
인스턴스가 생성되고 초기화된 후 프로퍼티 값에 접근하고 싶다면 마침표(.)를 사용하면 됩니다. 구조체를 상수 let으로 선언하면 인스턴스 내부의 프로퍼티 값을 변경할 수 없고, 변수 var로 선언하면 내부의 프로퍼티가 var로 선언된 경우에 값을 변경해줄 수 있습니다. 

// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다. var yagomInfo: BasicInformation = BasicInformation(name: "yagom", age: 99) yagomInfo.age = 100 // 변경 가능! yagomInfo.name = "Bear" // 변경 가능! // 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다. let hanaInfo: BasicInformation = BasicInformation(name: "hana", age: 99) hanaInfo.age = 100 // 변경 불가!


클래스

클래스를 어떻게 정의하고 클래스의 인스턴스를 어떻게 생성하는지 그리고 클래스를 어떻게 활용하는지에 대해 알아보겠습니다. 스위프트의 클래스는 부모클래스가 없더라도 상속 없이 단독으로 정의가 가능합니다. 

클래스 명명법


클래스를 정의할 때에는 class라는 키워드를 사용합니다. 

class [클래스 이름] { 
	[프로퍼티와 메서드들]
} 
클래스를 정의하는 방법은 구조체와 흡사합니다. 다만, 클래스는 상속받을 수 있기 때문에 상 속받을 때에는 클래스 이름 뒤에 콜론(:)을 써주고 부모클래스 이름을 명시합니다. 
class [클래스 이름]: [부모클래스 이름] { 
	[프로퍼티와 메서드들]
}
사람의 기본정보를 프로퍼티로 갖는 클래스를 정의해보겠습니다.

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}
위에 정의된 클래스는 Float 타입인 height와 weight 저장 프로퍼티가 있는 Person 클래스입니다. 

클래스 인스턴스의 생성과 초기화


클래스를 정의한 후, 클래스의 인스턴스를 생성하고 초기화하고자 할 때에는 기본적인 이니셜라이저를 사용합니다. 위 코드의 Person 클래스에서는 프로퍼티의 기본값이 지정되어 있으므로 전달인자를 통하여 따로 초깃값을 전달해주지 않아도 됩니다. 
인스턴스가 생성되고 초기화된 후(이니셜라이즈된 후) 프로퍼티 값에 접근하고 싶다면 마침표(.)를 사용하면 됩니다. 구조체와는 다르게 클래스의 인스턴스는 참조 타입이므로 클래스의 인스턴스를 상수 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있습니다. 구조체 코드와 클래스 코드를 비교해보세요.

var yagom: Person = Person() yagom.height = 123.4 yagom.weight = 123.4 let hana: Person = Person() hana.height = 123.4 hana.weight = 123.4


클래스 인스턴스의 소멸


클래스의 인스턴스는 참조 타입이므로 더는 참조할 필요가 없을 때 메모리에서 해제됩니다. 이 과정을 소멸이라고 칭하는데 소멸되기 직전 deinit라는 메서드가 호출됩니다. 클래스 내부에 deinit 메서드를 구현해주면 소멸되기 직전 deinit 메서드가 호출됩니다. 이렇게 호출 되는 deinit 메서드는 디이니셜라이저(Deinitializer)라고 부릅니다. deinit 메서드는 클래스당 하나만 구현할 수 있으며, 매개변수와 반환 값을 가질 수 없습니다. deinit 메서드는 매개변수를 위한 소괄호도 적어주지 않습니다. 또, 프로그래머가 직접 deinit 메서드를 호출할 수도 없습니다. 아래 코드에서 Person 클래스에 구현된 deinit 메서드 를 확인할 수 있습니다.

class Person { var height: Float = 0.0 var weight: Float = 0.0 deinit { print("Person 클래스의 인스턴스가 소멸됩니다.") } } var yagom: Person? = Person() yagom = nil // Person 클래스의 인스턴스가 소멸됩니다.

보통 deinit 메서드에는 인스턴스가 메모리에서 해제되기 직전에 처리할 코드를 넣어줍니다. 예를 들어 인스턴스 소멸 전에 데이터를 저장한다거나 다른 객체에 인스턴스 소멸을 알려야 할 때는 특히 deinit 메서드를 구현해야 합니다. 


구조체와 클래스의 차이

구조체와 클래스는 서로 비슷하거나 같은 점도 많습니다. 다음은 같은 점입니다. 
  • 값을 저장하기 위해 프로퍼티를 정의할 수 있습니다. 
  • 기능 수행을 위해 메서드를 정의할 수 있습니다. 
  • 서브스크립트 문법을 통해 구조체 또는 클래스가 가지는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있습니다. 
  • 초기화될 때의 상태를 지정하기 위해 이니셜라이저를 정의할 수 있습니다. 
  • 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있습니다. 
  • 특정 기능을 수행하기 위해 특정 프로토콜을 준수할 수 있습니다. 


그러나 확연히 다른 점도 존재합니다. 
  • 구조체는 상속할 수 없습니다.
  • 타입캐스팅은 클래스의 인스턴스에만 허용됩니다.
  • 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있습니다.
  • 참조 횟수 계산(Reference Counting)은 클래스의 인스턴스에만 적용됩니다. 


구조체와 클래스는 겉보기엔 정의하는 방법도, 인스턴스화하는 방법도, 프로퍼티와 메서드를 갖는다는 점을 비롯해 많은 부분에서 비슷해보입니다. 그러나 이 두 타입을 구분 짓는 가장 큰 차이점은 값 타입과 참조 타입이라는 것입니다. 그래서 참조 횟수 계산은 클래스의 인스턴스에만 해당됩니다. 




스위프트의 기본 데이터 타입은 모두 구조체

public struct String { /// An empty 'String'. public init() }

위의 코드는 스위프트 표준 라이브러리에 포함되어 있는 스위프트의 String 타입의 기본 정의 코드입니다. public은 잠시 제쳐두고, struct 키워드는 익숙하지 않으신가요? 네, 스위 프트의 다른 기본 타입(Bool, Int, Array, Dictionary, Set 등등)도 String 타입과 마찬 가지로 모두 구조체로 구현되어 있습니다. 그렇다는 의미는, 기본 데이터 타입은 모두 값 타입 이라는 뜻입니다. 전달인자를 통해 데이터를 전달하면 모두 값이 복사되어 전달될 뿐, 함수 내부에서 아무리 전달된 값을 변경해도 기존의 변수나 상수에는 전혀 영향을 미치지 못한다는 의미입니다. 이런 점을 더욱 확실히 하기 위해 스위프트의 전달인자는 모두 상수로 취급되어 전달되는 것일지도 모릅니다. 


구조체와 클래스 선택해서 사용하기 

구조체와 클래스는 모두 새로운 데이터 타입을 정의하고 기능을 추가한다는 점에서는 같습니다. 하지만 구조체 인스턴스는 항상 값 타입이고, 클래스 인스턴스는 참조 타입입니다. 그 의미는 생긴 것은 비슷하지만 용도는 다르다는 의미입니다. 프로젝트의 성격에 따라, 데이터의 활용 용도에따라, 특정타입을 구현할 때 구조체와 클래스 둘 중 하나를 선택해서 사용해야 합니다. 
애플은 가이드라인에서 다음 조건 중 하나 이상에 해당된다면 구조체를 사용하기를 권합니다. 
  • 연관된 간단한 값의 집합을 캡슐화 하는 것만이 목적일 때 
  • 캡슐화된 값이 참조되는 것보다 복사되는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값 타입이며 참조되는 것보다 복사되는 것이 합당할 때
  • 다른 타입으로부터 상속받거나 자신이 상속될 필요가 없을 때 

구조체로 사용하기에 가장 적합한 예로는 좌표계가 있습니다. x, y 좌표 등을 표현하고 싶을 때 Int 타입으로 x, y 프로퍼티를 가질 수 있으며, 물건의 크기를 표현하고자 할 때는 부동소수 표현인 Double 또는 Float 타입을 사용하여 width, height, depth 등으로 묶어 표현해 줄 수 있습니다. 
이런 몇 가지 상황을 제외하면 클래스로 정의하여 사용합니다. 대다수 사용자정의 데이터 타입은 클래스로 구현할 일이 더 많을 수 있습니다. 

이번에 스위프트의 구조체와 클래스에 대해 알아봤습니다. 다음 포스팅에서는 프로토콜과 익스텐션에 대해 알아보겠습니다. 
다음 번에 또 뵈어요~ 고맙습니다 :D




by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/

twitter : http://www.twitter.com/yagomSoft ( @yagomsoft )

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   



저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

스위프트 시작하기  (0) 2017.05.08
Swift - 프로토콜, 익스텐션  (0) 2017.03.07
Swift - 구조체 클래스  (0) 2017.02.28
Swift - 함수, 콜렉션 타입  (0) 2017.02.06
Swift 기초문법 - 변수, 상수, 기초 데이터 타입  (0) 2017.01.25
Swift란 어떤 언어인가?  (0) 2017.01.23
Posted by yagom

오늘의 주제

1. 연결 리스트 (Linked list)


열 여덟 번째 시간입니다.^^

지난 번에 동적 할당에 대하여 알아보았습니다~
오늘은 동적 할당과 구조체를 알고 계셔야 이해할 수 있습니다.ㅎ

2012/05/16 - [C] - C <16>. 구조체

2012/05/18 - [C] - C <17>. 동적할당

자. 오늘 내용은 난이도가 쪼깨 있습니다~
처음 보시는 분들은 다섯 번은 봐야 이해가 될랑 말랑 하실거예요..ㅎㅎ
물론 C의 문법은 아닙니다만(사실 C의 중요한 문법은 거의 끝났다고 봐야겠죠?), 자료구조 공부하심에 있어서 도움이 되실거예요~
정말 중요한 것이니 몇 번을 보고, 다른 싸이트를 검색하고, 직접 계속 둘러보면서 꼭 몸으로 익히도록 하세요~!

자 험난한 여정을 함께 즐겨 볼까요?ㅎ
스따뚜~~~~~~~~~~~~


# 연결리스트

연결리스트 입니다.
이녀석은 언뜻 보면 배열과 비슷합니다.
하지만 동작 방식과 생성 방식은 크게 다르죠~

배열은 메모리 상에서 다닥다닥 서로 붙어있기 때문에 접근하기 용이 합니다. 하지만 우리가 마음대로 개수를 늘렸다 줄였다 할 수가 없지요.

그래서 우리는 연결 리스트라는 녀석을 고안해 냅니다. 쭈욱 늘어선 녀석들을 자유롭게 추가/삭제 할 수 있게 된 겁니다~

하지만, 기본적으로 C에서 주어진 자료형이 아닌, 우리가 직접 스스로 만들어야 하는 어려움이 있습니다.

코드의 양이 적지 않습니다~

잘 따라오세요^^ 물론 역시나 상세한 설명은 주석으로 남깁니다.

헤더 파일입니다.  (yagom.h)
연결리스트의 원소가 될 구조체를 처음에 선언 해 두었구요.
연결리스트 관리를 위한 함수들을 선언해 주었습니다.


구현 파일입니다. (yagom.c)
메인 함수를 구현합니다.


그 후에 헤더에 선언해 놓았던 함수들을 메인함수 아래쪽에 차례대로 작성해 줍니다.


그리고 실행을 해 볼까요?


자 이런식으로 우리는 연결리스트를 배열처럼 사용 할 수 있습니다.

어떤가요? 연결리스트라는 녀석, 비록 복잡하고 속도는 느리지만 용도에 따라 적절히 사용한다면 정말 매력적이 녀석이 됩니다^^*

그럼 다음에 또 뵈어요~^^*

by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 



저작자 표시 비영리 변경 금지
신고

'C' 카테고리의 다른 글

C <20>. enum  (4) 2012.05.24
C <18>. 연결리스트 (Linked list) - 자료구조(1)  (0) 2012.05.21
C <17>. 동적할당  (2) 2012.05.18
C <16>. 구조체  (2) 2012.05.16
C <15>. 전처리자  (0) 2012.05.14
C <14>. 배열  (4) 2012.05.11
Posted by yagom

C <16>. 구조체

C 2012.05.16 12:30

오늘의 주제

1. 구조체 


열 여섯 번째 시간입니다.^^

지난 번에는 전처리자에 대해 알아보았습니다.
잘만 사용하면 좋지만, 잘못 사용한다면 독이 될 수 있는 녀석입니다.
사용에 유의하세요^^

오늘은 또 하나의 개념 구조체에 대해 알아보도록 하겠습니다.

자 그럼 이제 시작해 볼까요?^^
스따뚜~~~~~~~~~~~~

그 전에 추천 한 방 부탁~~~~~~~해요~~~~~~
저에게 큰 힘이 됩니다. ^~^




# 구조체의 개념


간단 합니다.
이 녀석은 배열과는 다르게 서로 다른 종류의 자료들이 들어갈 수 있습니다.

큰~~~~~~~ 박스 안에 서로 다른 크기의 작은 박스들이 들어가 있는 형태라고 보시면 되겠습니다.

그래서 우리가 큰 박스를 만들고 그 안에 작은 박스들을 만들어 넣습니다.

선언하는 방법은

struct 구조체이름 {
  내용물(변수들 선언)
} 구조체변수이름;


한 번 구조체 이름으로 선언 해 주면
다음 번에는 
struct 구조체이름 구조체변수이름;
이라고 선언 해 줄 수도 있습니다.

구조체 안의 변수에 접근하는 방법은

구조체변수명.내용물변수이름

이런식으로 접근하게 됩니다.

말로 하니까 어렵네요 ㅎ 예제를 한 번 봅시다요~

# 구조체 예제
 


yagom이라는 이름의 구조체를 tYagom, tAgainYagom 이라고 선언해 준 형태입니다.
yagom이라는 이름의 구조체 안에는 int형 변수 nNum과 char 포인터형 변수 szName이 들어가 있네요~
그곳에 접근하는 방법은 .  을 통해서 접근하는 것이죠.


결과 캡쳐입니다. 다들 예상대로 출력이 되었나요?ㅎ

그런데 구조체를 선언 할 때 마다 struct yagom 이렇게 하기가 좀 귀찬습니다...ㅎㅎ

그래서 조금이라도 더 간단히 하기 위해서 우리는 이렇게도 선언을 할 수 있습니다.

typedef 라는 녀석을 이용하는데요.

typedef는 어떠한 형태의 타입을 나는 이렇게 정의 하겠다, 라고 말해주는 것으로써 #define이랑 하는 짓은 비슷합니다만, 정의 해 줄 녀석이 아무거나가 아니라 자료형이라는 점이 다릅니다.

typedef int my;
이런 식으로 해주면
int a; 라고 선언 한 것과 my a; 라고 선언 한 것과 동일한 효과를 가져오게 됩니다.

그러므로 typedef struct yagom{ ...} yagom; 이런 식으로 선언을 해준다면 struct yagom{...} 과 yagom과 같아지는 효과를 보게 되겠지요.

말로는 잘 이해가 다가오지 않죠?ㅎ 실습 해 봅시다.


위에 그림처럼 struct yagom을 한 것과 그냥 yagom이라고 한 것과 같은 효과를 볼 수가 있네요~


자, 이렇게 해서 구조체에 대해 간단히 알아보았습니다.

참, 오늘 빼먹은 것이 있는데, 만약 구조체의 포인터변수에서 내부의 변수에 접근을 하려면 . 을 사용하는 것이 아니라 ->을 사용하게 됩니다.

잘 이해가 안가시면 다다음 번 포스팅 때 제대로 볼 수 있으실 거예요~ㅎ

그럼 다음에 또 뵈어요~^^&

by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 



저작자 표시 비영리 변경 금지
신고

'C' 카테고리의 다른 글

C <18>. 연결리스트 (Linked list) - 자료구조(1)  (0) 2012.05.21
C <17>. 동적할당  (2) 2012.05.18
C <16>. 구조체  (2) 2012.05.16
C <15>. 전처리자  (0) 2012.05.14
C <14>. 배열  (4) 2012.05.11
C <13>. 변수의 범위  (0) 2012.04.05
Posted by yagom


티스토리 툴바