Literal Initializer 만들기
최근 공부하다가 Literal이라는 것을 접하게 되었고
이 Literal이 Swift에서 어떻게 쓰이는 지 알고 적용해보고 싶었다!
Literal Initializer 만들기
Literal이란 소스코드의 어떤 값을 대표하는 것입니다.
예를 들어 0은 Integer, 0.0은 Floating-Point, "AAA"는 String과 같이 어떤 값이 주어지면 그 값을 대표하는 것이 Literal입니다.
이 Literal은 Swift에서 Protocol로 제공되고 있습니다.
Literal |
Protocol |
Integer | ExpressibleByIntegerLiteral |
Floating-Point | ExpressibleByFloatLiteral |
String | ExpressibleByStringLiteral |
Extended Grapheme Cluster | ExpressibleByExtendedGraphemeClusterLiteral |
Unicode Scalar | ExpressibleByUnicodeScalarLiteral |
Boolean | ExpressibleByBooleanLiteral |
Nil | ExpressibleByNilLiteral |
Array | ExpressibleByArrayLiteral |
Dictionary | ExpressibleByDictionaryLiteral |
모든 Protocol이 Expressible@@@Literal과 같은 모양을 하고 있군요..!
(이 Literal들은 모두 typealias로 @@@LiteralConvertible로도 제공되고 있습니다 🙂)
그렇다면 이 Literal이 어떻게 쓰이는 지 보도록 하겠습니다.
var number: Int = 5
type(of: number) // Int
number에 Int(5) 이렇게 변수 할당을 하지 않고 단순히 5만 넣어도 Int Type이란 것을 알 수 있습니다.
당연하다고 생각되지만 Int를 Tracking해보면
public struct Int : FixedWidthInteger, SignedInteger { ... }
public protocol SignedInteger : BinaryInteger, SignedNumeric { }
public protocol SignedNumeric : Numeric { ... }
public protocol Numeric : Equatable, ExpressibleByIntegerLiteral { ... } // *
Int Struct가 준수하고 있는 protocol을 쭉 올라가다보면 결국 Numeric이란 Protocol을 준수하고 있습니다.
(다른 UInt등 숫자와 관련된 struct모두 Numeric protocol을 준수하고 있습니다.)
Numeric Protocol은 어떤 Protocol을 준수하고 있는 지 보이시나요?
바로 ExpressibleByIntegerLiteral protocol을 준수하고 있습니다!
그래서 변수 할당을 할때 타입을 지정해주지 않아도 저 Literal에 따라 Int로 타입이 결정되는 것이죠.
(제 추측입니다...! 😅)
그렇다면 이 Literal을 이용해보겠습니다 ㅎㅎㅎ
먼저 아래와 같이 Person struct가 있다고 생각해봅시다.
struct Person {
var height: Double
init(height: Double) {
self.height = height
}
}
let person: Person = Person(height: 165.3)
person 변수에 Person을 할당할 때, Person initializer를 이용하여 할당했습니다.
그런데 이렇게 말고 아래와 같이 초기화하고 싶습니다.
let person: Person = 165.3
이렇게 초기화하기 위해선 ExpressibleByFloatLiteral을 이용해봅시다!
struct Person {
var height: Double
init(height: Double) {
self.height = height
}
}
extension Person: ExpressibleByFloatLiteral {
init(floatLiteral value: FloatLiteralType) {
self.init(height: value)
}
}
let person: Person = 165.3
기존 Person struct를 extension하여 ExpressibleByFloatLiteral protocol을 준수하고
새로운 initializer를 만들어 제공하면 원하던 방식으로 초기화 할 수 있습니다! 👍
위와 같은 초기화 방법이 얼마나 많이 쓰일지 모르지만 그래도 새로운 지식도 얻고
흥미로운 protocol을 알게 되었습니다...! ㅎㅎ
나중에 이 Literal을 이용할 기회가 생긴다면 적극 이용해보겠습니다.. ㅎㅎ