CustomStringConvertible

description property

var description: String { get }

 

description 프로퍼티를 통해 인스턴스의 텍스트 표현을 할 수 있습니다.

print(_:) 함수로 인스턴스를 출력하고자 할 때, 인스턴스의 description 프로퍼티를 사용합니다.

그렇다는 것은 인스턴스 내부에 description을 정의해주지 않아도 이미 구현이 되어있다는 것입니다.

예를 들면, CGFloat 데이터 타입에는 description property가 구현되어 있음을 확인할 수 있었습니다.

extension CGFloat : CustomStringConvertible {
    /// A textual representation of `self`.
    public var description: String {
        return native.description
    }
}

 

그 이유인 즉, 데이터 타입이 CustomStringConvertible protocol을 준수하고 있기 때문입니다.

 

CustomStringConvertible protocol

protocol CustomStringConvertible

 

애플 공식 문서에는 CustomStringConvertible을 다음과 같이 정의합니다.

CustomStringConvertible 프로토콜은 인스턴스를 문자열로 변환하는 자체 표현을 제공합니다.

CustomStringConvertible 프로토콜을 준수하기 위해서는 description 프로퍼티를 구현해야 합니다.

이 프로토콜을 정의하지 않고 사용자가 정의한 구조체를 출력하면 표준 라이브러리에서 제공하는 기본 표현을 사용합니다.

struct Point {
    let x: Int, y: Int
}

let p = Point(x: 21, y: 30)
print(p) // "Point(x: 21, y: 30)\n"

 

CustomStringConvertible 프로토콜을 준수하면 Point 타입은 사용자 정의 표현을 제공합니다.

 

extension Point: CustomStringConvertible {
    var description: String {
        return "(\(x), \(y))"
    }
}
print(p) // "(21, 30)"

 

 

애플 문서에서 인스턴스의 description을 직접 접근하거나 일반 제약 조건으로 CustomStringConvertible을 사용하는 것을 금지하고 있습니다.

String(describing:) 생성자와 print(_:) 함수는 인스턴스의 description 프로퍼티를 사용합니다.


추가질문거리

  • Swift 모듈에 정의되어 있는 데이터 타입에 확장 문법(extension)을 통해 CustomStringConvertible 프로토콜을 준수할 수 있을까요?

다음과 같이 Array 타입에 CustomStringConvertible 프로토콜을 채택한 뒤, description 프로퍼티를 사용자 정의된 문자열을 반환하도록 준수하였습니다.

extension Array: CustomStringConvertible {
    var description: String {
        return self.map { "\($0)" }.joined(separator: ", ")
    }
}

 

그러나 Array 타입에 프로토콜을 준수하면, 다음의 컴파일 경고가 나타나게 됩니다.

Conformance of 'Array' to protocol 'CustomStringConvertible' was already stated in the type's module 'Swift'

이미 Swift 모듈에 명시된 Array의 CustomStringConvertible 프로토콜 준수가 충돌하여 무시되었다고 경고합니다.

물론, Array 타입을 기존과 다르게 표현할 방법은 있습니다. 하지만 이 방법은 추천하지 않습니다.

기존 타입을 변경시켜 의도한 것과 다른 것을 할 수 있다는 장점이 있을 수 있지만, 프로그램 전반의 행동에 변화를 줄 수 있기 때문입니다.

사용자가 새로 정의한 타입에 CustomStringConvertible 프로토콜을 준수하는 것이 올바른 사용방법이라고 할 수 있겠습니다.

 


참고

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

https://forums.swift.org/t/whats-the-best-way-to-override-customstringconvertible-for-a-collection/24844

댓글