[Swift 기초] 사용자정의타입

2022. 3. 18. 18:09Swift 기초 정리

728x90

//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎

 

 

1. 구조체

struct 이름 {
	/* 구현부 */
}
struct Sample{
	//타입안에 들어가있는 변수: 프로퍼티
  
  //인스턴스 프로퍼티
	var mutableProperty: Int //가변 프로퍼티
	let immutableProperty: String //불변 프로퍼티 - 인스턴스 생성 후 수정할 수 없음
	
	//타입 프로퍼티
	static var typeProperty: Int

	//타입안에 들어가있는 함수: 메서드

	//인스턴스 메서드
	func instanceMethod(){
	}
	//타입 메서드
	static func typeMethod(){
	}
}
  • 구조체(Structures): 서로 다른 자료형의 변수들을 묶어 하나의 새로운 자료형을 만들 수 있으며, 이 새로운 자료형을 구조체(struct)라고 한다.
  • 속성과 메소드를 가질 수 있다.
  • 값타입

1-1. 구조체 사용

struct Sample {
	var mutableProperty: Int = 100
	let immutableProperty: Int = 100
	static var typeProperty: Int = 100
	
	func instanceMethod(){
	}
	static func tyepMethod(){
	}
}

//인스턴스 선언
var test: Sample = Sample()
//프로퍼티 접근 - 접근연산자(.)
test.mutableProperty

1-2. 가변 인스턴스와 불변 인스턴스

  • 불변 프로퍼티는 인스턴스 생성 후 수정할 수 없다. (let)
    • 'immutableProperty' is a 'let' constant
  • 불변 인스턴스는 아무리 가변 프로퍼티라도 인스턴스 생성 후에 수정할 수 없다.
    • 'immutable' is a 'let' constant
//가변 인스턴스 생성
var mutable: Sample = Sample()
mutable.mutableProperty = 200  //200
mutable.immutableProperty = 200  //'immutableProperty' is a 'let' constant

//불변 인스턴스 생성
let immutable: Sample = Sample()
immutable.mutableProperty = 200 //'immutable' is a 'let' constant

1-3. 인스턴스와 타입

struct Student {
    var name: String = "noName"
    var `class`: String = "stopStudy"
    //타입 메서드
    static func selfIntroduce(){
        print("인스턴스를 생성하지 않는 타입입니다.")
    }
    //인스턴스 메서드
    //self는 인스턴스 자신을 지칭
    func selfIntroduce(){
        print("\\(self.class)반 \\(name)입니다.")
    }
}
    
//타입 메서드 사용 - 인스턴스 생성 X
Student.selfIntroduce()  //인스턴스를 생성하지 않는 타입입니다.

//인스턴스 생성
var makeInstance: Student = Student()
makeInstance.name = "4학년"
makeInstance.class = "응애"
makeInstance.selfIntroduce()  //응애반 4학년입니다.

1-4. 구조체의 초기화(init)

struct Celsius{
    var temperatureInCelsius: Double 
    init(fromFahrenheit fahrenheit: Double){
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double){
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
let freezingPointOfWater = Celsius(fromKelvin: 273.15)

1-5. 구조체의 변경가능, 불가능 속성

  • 구조체의 인스턴스 생성 후에는 메소드를 통해서 해당 인스턴스의 속성을 변경할 수 없다. 하지만 → 메소드가 구조체의 프로퍼티를 변경하게 하려면 mutating 사용
  • 메소드의 디폴트 상태는 변경 불가능(immutable)이다. struct의 디폴트 변경모드가 변경 가능(mutable) 일 경우 내부 속성의 변경이 가능하므로 버그의 원인이 되며, 예측가능하지 않다.
    • Mark method ‘mutating’ to make ‘self’ mutable
    • 구조체의 메소드는 immutable로 프로그램의 안정성에 기여하고 버그를 줄이는 역할을 한다.
  • 구조체 인스턴스가 상수 타입의 변수에 할당될 때는 mutating을 사용할 수 없다.
  • class의 메소드는 mutable 하다.
struct Point0{
    var x = 0.0, y = 0.0
    //func moveByX(deltaX: Double, deltaY: Double){
    //    x += deltaX
    //    y += deltaY
    //}
		//Mark method ‘mutating’ to make ‘self’ mutable
		
		//메소드가 프로퍼티의 값을 변경가능하다 를 명시: mutating
		mutating func moveByX(deltaX: Double, deltaY: Double){
        x += deltaX
        y += deltaY
    }
}

var somePoint = Point0()
somePoint.x = 100
somePoint.y = 100
somePoint.moveByX(deltaX: 2.0, deltaY: 3.0)
print(somePoint.x) //102.0

 

2. 클래스

class 이름 {
	/* 구현부 */
}
class Sample {
	//가변 프로퍼티
	var mutableProperty: Int = 100
	//불변 프로퍼티
	let immutableProperty: Int = 100
	//타입 프로퍼티
	static var typeProperty: Int = 100

	//인스턴스 메서드
	func instanceMethod() {
	}
	
	//타입 메서드
	//static - 상속 받았을 때 재정의 불가 타입 메서드
	static func typeMethod(){
	}
	//calss - 상속 받았을 때 재정의 가능 타입 메서드
	class func classMethod() {
	}
}
  • 클래스(Class): 클래스는 구조체와 같이 서로 다른 자료형의 속성과 메소드를 포함한다. 상속을 통해 자식 클래스에 자신의 속성과 메소드를 물려줄 수 있다.
    • 다중상속 X
  • 속성과 메소드를 가질 수 있다.
  • 참조타입

2-1. 클래스 사용, 참조정보 수정

//인스턴스 생성 - 참조정보 수정 가능(var)
var mutableReference: Sample = Sample()
mutableReference.mutableProperty = 200

//인스턴스 생성 - 참조정보 수정 불가(let)
let immutableReference: Sample = Sample()

//클래스의 인스턴스는 참조타입이므로 let으로 선언되었더라도 인스턴스 프로퍼티의 값 변경이 가능하다(var mutableProperty)
immutableReference.mutableProperty = 300

//참조타입이라도 불변 인스턴스는 인스턴스 생성 후에 수정할 수 없다.
//immutableReference.immutableProperty = 300

//참조정보를 변경할 수는 없다.
//immutableReference = mutableReference

//타입 프로퍼티 및 메서드 - 인스턴스에서는 사용할 수 없다.
Sample.typeProperty = 300
Sample.typeMethod()
  • 구조체와 다르게 클래스에서 let으로 인스턴스를 생성해도 가변 인스턴스 프로퍼티의 값은 변경할 수 있다.
    • let immutableReference - var mutableProperty

 

3. 클래스와 구조체

3-1. 클래스와 구조체의 유사점

  • 값을 저장할 속성을 정의한다.
  • 기능을 위한 메소드를 정의한다.
  • 멤버 속성의 설정과 검색을 위해서 메소드를 만들 수도 있으나 subscript을 사용하여 인덱스로 값을 편리하게 설정하고 검색할 수 있다.
  • 초기상태를 설정하기 위한 init이라는 초기설정자를 제공한다.
  • 기본 구현내용을 확장하기 위한 기능을 제공한다(extension)

3-2. 클래스와 구조체의 차이점(클래스는 구조체가 가지지 못한 다음 기능을 가진다.)

  • 부모 클래스의 특성을 상속받는 기능이 가능하다.
  • 클래스 인스턴스를 형을 검사하고 번형 하여 런타임시에 형변환을 할 수 있다.
  • 할당된 임의의 리소스를 해지하는 deinitializer를 가진다.
  • 클래스 인스턴스는 참조 카운터를 하나 이상 허용한다.

 

4. 열거형

enum 변수명 {
    case 멤버1, 멤버2, ...
}
  • 열거형(enumeration 또는 enum): 서로 연관된 상수 집합에 사용되는 정의된 타입
    • 타입 안전이 보장됨: 프로그래밍 언어에서 타입 에러를 방지하는 것
    • 타입 에러: 기대하는 타입과 제공된 타입 간에 차이가 있을 때 발생
  • 변수가 가질 수 있는 가능한 값들을 나열해 놓은 타입
    • 값의 종류가 일정한 범위로 정해 있을 때 쓰는 것이 편리
  • 각 case 그 자체가 고유의 값
  • C언어는 디폴트로 멤버에 정수를 할당하지만 Swift에서는 정수 할당 여부를 선택할 수 있다.

4-1. 열거형 사용

  • 열거형 예시) 요일 - 유사한 데이터의 제한된 집합
enum Weekday {
	case mon
	case tue, wed
	case thu, fri, sat, sun
}
  • enum 키워드는 열거형을 나타냄
  • {} 열거형을 정의하는 코드 블록이 포함
  • case 키워드는 열거형 멤버를 정의할 때 사용
  • Week.Monday Week 타입이면서 특정 Week 값을 갖는 변수를 생성
    var day = Week.Monday    //Week 타입의 변수를 선언
    day = .Tuesday           //값을 변경할 때는 더 이상 참조 표기(Week.)를 하지 않아도 된다
    var mon:Week = .Monday   //명시적인 타입 선언도 사용할 수 있다
    • 값을 변경할 때는 더 이상 참조 표기(Week.)를 하지 않아도 된다.
    • 명시적인 타입 선언도 사용할 수 있다
      • 열거형 타입과 케이스를 모두 사용해도 된다.
      • 타입이 명확하다면 .케이스 처럼 사용해도 무방하다.
  • 타입 안전 보장
day = .holiday    //'Week' 유형에는 'holiday' 구성원이 없습니다.
  • switch문의 비교 값에 열거형 타입이 위치할 때 모든 열거형 케이스를 포함하면 default 작성할 필요는 없다.

4-2. 튜플을 멤버값으로 사용하는 열거형

enum Barcode{
    case UPCA(Int, Int, Int, Int), QRCodes(String)
}

var productBarcode = Barcode.UPCA(1, 1, 1, 1)
productBarcode = .QRCodes("qr")

//switch문에서 사용할 때
switch productBarcode{
case .UPCA(let n1, let n2,  let n3, let n4):
    print("UPCA: \\(n1), \\(n2), \\(n3), \\(n4)")
case .QRCodes(let productCode):
    print("QR: \\(productCode)")
}

4-3. 원시값

enum 변수명: 자료형 {
	case 멤버 1 = 원시값1, 멤버2 = 원시값 2, ...
}
  • 원시값(Raw values): 멤버가 가지는 이름에 데이터 값을 부여할 수 있다. 주로 숫자를 할당하여 편리하게 이용할 수 있다.
  • rawValue 속성을 이용해서 원시값을 읽어올 수 있다.(읽기 전용)
  • case 별로 각각 다른 값을 가져야 한다.
enum Planet: Int{
    case Mercury = 1, Venus, Earth, Mars, Jupitor, Saturn, Uranus, Neptune
}
print(Planet.Mercury)  //Mercury
print(Planet.Mercury.rawValue)  //1
print(Planet.Venus.rawValue)  //2

//정수 타입일 때 원시값을 지정하지 않으면 0부터 시작
enum Planets: Int{
    case Mercury, Venus, Earth, Mars, Jupitor, Saturn, Uranus, Neptune
}
print(Planets.Mercury.rawValue)  //0
print(Planets.Venus.rawValue)  //1

//정수타입 뿐만 아니라 다른 타입도 원시값으로 지정 가능
enum School: String{
    case elementry = "초등", middle = "중등", high = "고등"
    case university
}
print(School.elementry)  //elementry
print(School.elementry.rawValue)  //초등
print(School.university.rawValue)  //university - case의 이름을 원시값으로 사용
  • 정수 타입일 때 원시값을 지정하지 않으면 0부터 시작
  • Hashable 프로토콜을 따르는 모든 타입이 원시값의 타입으로 지정될 수 있다.
  • 열거형의 원시값 타입이 String일 때, 원시값이 지정되지 않았다면 case의 이름을 원시값으로 사용

4-4. 원시값을 통한 초기화

  • rawValue를 통해 초기화할 수 있다.
  • rawValue가 할당되지 않은 case가 있을 수 있으므로 rawValue를 통해 초기화한 인스턴스는 옵셔널 타입이다.
//원시값을 이용하여 멤버를 찾고, 옵셔널 값 리턴
//옵셔널 바인딩
let somePlanet = Planet(rawValue: 100)
print(somePlanet)  //nil

let anotherPlanet: Planet? = Planet(rawValue: 3)
print(anotherPlanet!)  //Earth

4-5. 열거형 메서드

  • swift의 열거형에는 메서드도 추가할 수 있다.
enum Month {
    case dec, jan, feb
    case mar, apr, may
    case jun, jul, aug
    case sep, oct, nov

    func printMessage() {
        switch self {
        case .mar, .apr, .may:
            print("따스한 봄~")
        case .jun, .jul, .aug:
            print("여름 더워요~")
        case .sep, .oct, .nov:
            print("가을은 독서의 계절!")
        case .dec, .jan, .feb:
            print("추운 겨울입니다")
        }
    }
}

Month.mar.printMessage()
// 따스한 봄~

 

 

 

참고하였습니다. 감사합니다.

https://yagom.net/courses/swift-basic/lessons/사용자정의-타입/

 

스위프트 기초 - 야곰닷넷

스위프트는 문법표현의 다양성이 매우 높은 언어입니다. 그래서 스위프트 문법의 모든 형태를 알기는 꽤 오랜 시간이 걸립니다. 그렇지만 최소한의 핵심 문법을 통해 무리없이 스위프트 문법을

yagom.net

https://www.inflearn.com/course/창원대학교-박동규-교수의-swift-기초-강좌/lecture/1896?tab=curriculum 

 

학습 페이지

 

www.inflearn.com

23.07.06 수정) Swift 쉽게, 더 쉽게

https://www.yes24.com/Product/Goods/17652267

728x90

'Swift 기초 정리' 카테고리의 다른 글

[Swift 기초] 프로퍼티  (0) 2022.03.31
[Swift 기초] 참조타입과 값타입  (0) 2022.03.19
[Swift 기초] 클로저 Closure  (0) 2022.03.14
[Swift 기초] 제너릭  (0) 2022.03.11
[Swift 기초] 함수  (0) 2022.03.11