[swift] Swift에서 변수의 유형 또는 클래스를 어떻게 인쇄합니까?

변수의 런타임 유형을 신속하게 인쇄하는 방법이 있습니까? 예를 들면 다음과 같습니다.

var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)

println("\(now.dynamicType)")
// Prints "(Metatype)"

println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector

println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method

위의 예에서 변수 “soon”이 유형 ImplicitlyUnwrappedOptional<NSDate>이거나 적어도 임을 보여주는 방법을 찾고 NSDate!있습니다.



답변

2016 년 9 월 업데이트

스위프트 3.0 : 사용 type(of:), 예를 들어 type(of: someThing)합니다 (이후 dynamicType키워드가 제거되었습니다)

2015 년 10 월 업데이트 :

아래 예제를 새로운 Swift 2.0 구문으로 업데이트했습니다 (예 : println로 바뀌 었습니다 print. toString()는 이제 String()).

Xcode 6.3 릴리스 정보 :

@nschum은 Xcode 6.3 릴리스 노트 가 다른 방법을 보여줍니다.

println 또는 문자열 보간과 함께 사용하면 유형 값이 완전한 얽힌 유형 이름으로 인쇄됩니다.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self)           -> \(Int.self)")
print( "String((Int?).self         -> \((Int?).self)")
print( "String(NSString.self)      -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

어떤 출력 :

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self)           -> Int
String((Int?).self         -> Optional<Int>
String(NSString.self)      -> NSString
String(Array<String>.self) -> Array<String>

Xcode 6.3 업데이트 :

당신은 사용할 수 있습니다 _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

이것을 출력으로 얻습니다.

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

원래 답변 :

Xcode 6.3 이전에는 _stdlib_getTypeName변수의 맹 글링 된 유형 이름이있었습니다. Ewan Swick의 블로그 항목 은 다음 문자열을 해독하는 데 도움이됩니다.

예를 들어 _TtSiSwift의 내부 Int유형을 나타냅니다 .

Mike Ash는 같은 주제를 다루는 훌륭한 블로그 항목을 가지고 있습니다.


답변

편집 : Swift 1.2 (Xcode 6.3)에 새로운 toString기능 이 도입되었습니다 .

이제 다음을 사용하여 모든 유형의 얽힌 유형을 인쇄하고 .self인스턴스를 사용할 수 있습니다 .dynamicType.

struct Box<T> {}

toString("foo".dynamicType)            // Swift.String
toString([1, 23, 456].dynamicType)     // Swift.Array<Swift.Int>
toString((7 as NSNumber).dynamicType)  // __NSCFNumber

toString((Bool?).self)                 // Swift.Optional<Swift.Bool>
toString(Box<SinkOf<Character>>.self)  // __lldb_expr_1.Box<Swift.SinkOf<Swift.Character>>
toString(NSStream.self)                // NSStream

YourClass.self와으로 전화하십시오 yourObject.dynamicType.

참조 : https://devforums.apple.com/thread/227425 .


답변

스위프트 3.0

let string = "Hello"
let stringArray = ["one", "two"]
let dictionary = ["key": 2]

print(type(of: string)) // "String"

// Get type name as a string
String(describing: type(of: string)) // "String"
String(describing: type(of: stringArray)) // "Array<String>"
String(describing: type(of: dictionary)) // "Dictionary<String, Int>"

// Get full type as a string
String(reflecting: type(of: string)) // "Swift.String"
String(reflecting: type(of: stringArray)) // "Swift.Array<Swift.String>"
String(reflecting: type(of: dictionary)) // "Swift.Dictionary<Swift.String, Swift.Int>"


답변

찾고 계십니까?

println("\(object_getClassName(now))");

“__NSDate”를 인쇄합니다

업데이트 : Beta05부터는 더 이상 작동하지 않습니다.


답변

현재 Xcode는 버전 6.0 (6A280e)입니다.

import Foundation

class Person { var name: String; init(name: String) { self.name = name }}
class Patient: Person {}
class Doctor: Person {}

var variables:[Any] = [
    5,
    7.5,
    true,
    "maple",
    Person(name:"Sarah"),
    Patient(name:"Pat"),
    Doctor(name:"Sandy")
]

for variable in variables {
    let typeLongName = _stdlib_getDemangledTypeName(variable)
    let tokens = split(typeLongName, { $0 == "." })
    if let typeName = tokens.last {
        println("Variable \(variable) is of Type \(typeName).")
    }
}

산출:

Variable 5 is of Type Int.
Variable 7.5 is of Type Double.
Variable true is of Type Bool.
Variable maple is of Type String.
Variable Swift001.Person is of Type Person.
Variable Swift001.Patient is of Type Patient.
Variable Swift001.Doctor is of Type Doctor.


답변

Swift 1.2가 포함 된 Xcode 6.3부터는 유형 값을 전체 demangled로 간단히 변환 할 수 있습니다 String.

toString(Int)                   // "Swift.Int"
toString(Int.Type)              // "Swift.Int.Type"
toString((10).dynamicType)      // "Swift.Int"
println(Bool.self)              // "Swift.Bool"
println([UTF8].self)            // "Swift.Array<Swift.UTF8>"
println((Int, String).self)     // "(Swift.Int, Swift.String)"
println((String?()).dynamicType)// "Swift.Optional<Swift.String>"
println(NSDate)                 // "NSDate"
println(NSDate.Type)            // "NSDate.Type"
println(WKWebView)              // "WKWebView"
toString(MyClass)               // "[Module Name].MyClass"
toString(MyClass().dynamicType) // "[Module Name].MyClass"


답변

를 통해 클래스에 계속 액세스 할 수 있습니다 className(를 반환 String).

실제로 클래스를 얻는 방법은 여러 가지가 있습니다 ( 예 classForArchiver: classForCoder, classForKeyedArchiver(all return AnyClass!)).

프리미티브의 유형을 얻을 수 없습니다 (프리미티브는 클래스 가 아닙니다 ).

예:

var ivar = [:]
ivar.className // __NSDictionaryI

var i = 1
i.className // error: 'Int' does not have a member named 'className'

프리미티브 유형을 얻으려면을 사용해야 bridgeToObjectiveC()합니다. 예:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber