Swift - print 와 debugPrint 이야기
사실 얼마 전까지만 해도 debugPrint 라는 함수가 있는지 조차 몰랐었다. 뭐 이제서라도 알게 되었으니 메모도 할겸 print 와 debugPrint 에 대한 글을 써 본다.
print 함수야 다들 알 것이다. 그냥 콘솔에 문자열 찍는 함수다.
이 둘의 결정적인 차이는 문자열로 찍을 때 어떤 프로토콜을 따르냐에 있다. 일단 이해 안되더라도 아래 스크린샷을 보자. 플레이그라운드에서 이 둘을 테스트 한 결과이다.
debugPrint의 결과물은 뭔가 요상한 것들이 덧붙여져 있다.
여기서 파악해야 할 것은 프로그래머에 의해 넘겨진 데이터를 어떤 관점에서 파악이 가능하냐이다. 응? 어려운 말인가?
아래의 예제는 CustomStringConvertible 을 사용한 예제이다.
이제 결과가 다르겠지?
참고로 Swift 2.0 에서 print 함수와 debugPrint 함수의 원형은 아래와 같다.
사실 쉽고 단순한 내용이다. 그저 CustomStringConvertible 의 설명을 적기엔 내용이 너무 초라하고 print 나 debugPrint 만 따로 적기에도 초라해서 이 둘을 이리저리 섞어보니 이런 글이 탄생하게 되었다. :-)
[관련글] Swift 2.0 - 그 외 사소한(?) 변화들
[관련글] 스위프트(Swift) 가이드
print 함수야 다들 알 것이다. 그냥 콘솔에 문자열 찍는 함수다.
참고로 print 함수는 Swift 1.2 까지는 println 이라는 이름으로 불리었다가 Swift 2.0 부터는 print 로 이름이 바뀌었다.debugPrint 도 비슷하게 콘솔에 로그를 남기기 위한 용도의 함수이다.
이 둘의 결정적인 차이는 문자열로 찍을 때 어떤 프로토콜을 따르냐에 있다. 일단 이해 안되더라도 아래 스크린샷을 보자. 플레이그라운드에서 이 둘을 테스트 한 결과이다.
debugPrint의 결과물은 뭔가 요상한 것들이 덧붙여져 있다.
""Hello World"\n""Hello World" 부분만 안쪽에 따로 따옴표로 묶여있다. 이 녀석은 debugPrint 에 직접 넘겨준 별도의 String 값이다. 그 뒷쪽에 붙은 개행문자(\n)는 debugPrint 가 알아서 붙여준 기능이다.
여기서 파악해야 할 것은 프로그래머에 의해 넘겨진 데이터를 어떤 관점에서 파악이 가능하냐이다. 응? 어려운 말인가?
CustomStringConvertible
CustomStringConvertible 이라는 프로토콜은 print 등을 이용할 때 혹은 String으로 변환할 때의 약속을 정의한 프로토콜이다. 단순하게 description 이라는 String 타입의 프로퍼티 게터(getter)를 구현하면 되는 간단한 프로토콜이다.아래의 예제는 CustomStringConvertible 을 사용한 예제이다.
struct MyType: CustomStringConvertible { let value: Int var description: String { return "\(self.value)" } }이제 이 녀석을 이용해 시험해보자.
let v1 = MyType(value: 1) print(v1) // 콘솔에 "1\n" 이 찍힌다. debugPrint(v1) // 콘솔에 "1\n" 이 찍힌다.print나 debugPrint문을 이용해 MyType 인스턴스를 출력시키자 description 의 내용을 자동으로 받아와서 처리한다. 여기서 print와 debugPrint 의 결과가 같다는 것을 알아두고 다음으로 넘어가자.
CustomDebugStringConvertible
이번엔 Debug 라는 이름이 붙은 StringConvertible 프로토콜이다. 앞서 본 CustomStringConvertible 과 비슷한 방법으로 사용하고 비슷한 용도로 사용된다. 하지만 이번에는 debug 라는 이름이 붙어있으니 debugPrint 와 관련이 있지 않을까 예상된다면 바로 정답이다.struct MyType: CustomStringConvertible, CustomDebugStringConvertible { let value: Int var description: String { return "\(self.value)" } var debugDescription: String { return "MyType[\(self.value)]" } }앞의 예제에서 CustomDebugStringConvertible 을 추가로 붙였다. 이 프로토콜은 debugDescription 이라는 String 타입의 프로퍼티 게터(Getter)를 구현하기만 하면 된다.
이제 결과가 다르겠지?
let v2 = MyType(value: 2) print(v2) // 콘솔에 "2\n" 이 찍힌다. debugPrint(v2) // 콘솔에 "MyType[2]\n" 이 찍힌다.빙고! CustomDebugStringConvertible 은 debugPrint 에서만 호출되고 있는 것을 볼 수 있다.
결론
결론 낼 꺼리가 없는것 같다. 그냥 print는 CustomStringConvertible 과 친하고 debugPrint 는 CustomDebugStringConvertible 과 친하다 정도이다.참고로 Swift 2.0 에서 print 함수와 debugPrint 함수의 원형은 아래와 같다.
print(items: Any..., separator: String, terminator: String, toStream: &Target) debugPrint(items: Any..., separator: String, terminator: String, toStream: &Target)여기서 terminator 의 기본값은 "\n" 이다. 앞서 debugPrint를 이용해 "Hello World" 를 찍었을 때 "\n"이 별도로 표시되는 것을 볼 수 있는데 이 terminator의 값이 별도로 표시되도록 만들어 둔 거라고 생각하면 되겠다.
사실 쉽고 단순한 내용이다. 그저 CustomStringConvertible 의 설명을 적기엔 내용이 너무 초라하고 print 나 debugPrint 만 따로 적기에도 초라해서 이 둘을 이리저리 섞어보니 이런 글이 탄생하게 되었다. :-)
[관련글] Swift 2.0 - 그 외 사소한(?) 변화들
[관련글] 스위프트(Swift) 가이드
댓글
거기 찍히게 실행은 어떻게 하나요? Run 해봐도 안찍히는데
시뮬레이터도 같이 실행되고 시뮬 실행안되고 찍히게 할 수 있나요?
시뮬레이터는 iOS 프로젝트라면 당연히 실행되어야 합니다. 만약 그게 싫다면 아이폰 등 iOS 디바이스를 직접 연결해서 해당 디바이스에서 테스트 해 보거나, 아니면 macOS용 앱 프로젝트로 만들어서 시험해 보는 방법도 있겠지만 상황에 따라 다르겠지요.