prosource

Swift에서 변수의 유형 또는 클래스를 인쇄하려면 어떻게 해야 합니까?

probook 2023. 4. 18. 23:05
반응형

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이 "soon"의 ImplicitlyUnwrappedOptional<NSDate> "" " " " " "NSDate!.

2016년 9월 갱신

3.0: Swift 3.0 사용: ★type(of:) 예 , ) 。type(of: someThing))dynamicType(미국의

2015년 10월 갱신:

2.0 구문 Swift 2.0 구문)으로했습니다.println was was was was was was was 로 되었습니다.print,toString() is금 is is이다String()를 참조해 주세요.

Xcode 6.3 릴리즈 노트:

@nschum은 코멘트에서 Xcode 6.3 릴리즈 노트가 다른 방법을 나타낸다고 지적합니다.

println 또는 문자열 보간과 함께 사용하면 type values가 완전한 demplanged type 이름으로 출력됩니다.

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

원답:

.3 Xcode 6.3 이전 _stdlib_getTypeName변수 이름이 망가졌습니다.Ewan Swick의 블로그 엔트리는 다음 문자열을 해독하는 데 도움이 됩니다.

★★_TtSi Swift의 입니다.Intdiscloss.discloss.

Mike Ash는 같은 주제를 다루는 훌륭한 블로그 엔트리를 가지고 있습니다.

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

어떤 할 수 있게 되었습니다..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

Swift 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.

1.3에서는, 한Swift 1.2 Xcode 6.3 으로 할 수 .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은 a를 한다).String를 참조해 주세요.

은 여러 . 를 들어, 수업을 받는 방법은 여러 가지가 있습니다.classForArchiver,classForCoder,classForKeyedArchiver 반환(모두 반환)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

반사를 사용하여 개체에 대한 정보를 가져올 수 있습니다.
「 」 「 」 、 「 」 。

var classname = reflect(now).요약

Xcode 8 Swift 3.0 사용 유형(/)

let className = "\(type(of: instance))"

운이 좋았습니다.

let className = NSStringFromClass(obj.dynamicType)

SWIFT 5

에서는 Swift 3을 유형 에 대한 수 .StringLike ( Like)print(String(describing: type(of: object)))서.어디에object 어레이, 딕셔너리, precision 등의 인스턴스 변수가 될 수 있습니다.Int ,a ,aNSDate 클래스의

Swift에서 객체의 클래스 이름을 문자열로 가져옵니다.

것입니다 이 질문은 객체의 서브클래스가하고 있습니다.NSObject

class Utility{
    class func classNameAsString(obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
}

.Any한다.String . : ).

다음과 같은 변수를 사용하여 이 함수를 테스트했습니다.

    let diccionary: [String: CGFloat] = [:]
    let array: [Int] = []
    let numInt = 9
    let numFloat: CGFloat = 3.0
    let numDouble: Double = 1.0
    let classOne = ClassOne()
    let classTwo: ClassTwo? = ClassTwo()
    let now = NSDate()
    let lbl = UILabel()

출력은 다음과 같습니다.

  • 사전은 사전 유형입니다.
  • 어레이가 어레이 유형입니다.
  • numInt는 Int 유형입니다.
  • numFloat은 CGFloat 유형입니다.
  • numDouble은 Double 유형입니다.
  • class One의 종류:클래스 원
  • class 2는 다음과 같습니다.클래스 투
  • 현재 유형:날짜.
  • lbl의 종류:유라벨

Xcode 8, Swift 3.0에서는

순서:

1. 유형 가져오기:

옵션 1:

let type : Type = MyClass.self  //Determines Type from Class

옵션 2:

let type : Type = type(of:self) //Determines Type from self

2. 유형을 문자열로 변환:

let string : String = "\(type)" //String

3.에서는 Swift 3.0을 사용할 수 .type(of:) ~로dynamicType이치노

Swift에서 개체 유형 또는 개체 클래스를 가져오려면 유형(오브젝트: yourObject)

type(오브젝트: yourObject

(코코아 )를 할 수 .classNameNSObject의 경우

println(now.className)

이 속성은 NSObject의 하위 클래스가 아닌 일반 Swift 개체에는 사용할 수 없습니다(실제로 Swift에는 루트 ID 또는 개체 유형이 없습니다).

class Person {
    var name: String?
}

var p = Person()
println(person.className) // <- Compiler error

코코아에서현재 지정된 변수 유형에 대한 문자열 설명을 가져올 수 있는 방법은 없습니다.코코아 또는 코코아의 원시 유형에는 유사한 기능이 존재하지 않는다.만지다.

Swift REP는 그 유형을 포함한 값의 요약을 인쇄할 수 있기 때문에 향후 API를 통해 이러한 자기성찰 방식이 가능할 수 있습니다.

EDIT: 효과가 있는 것 같습니다.

에는 이 type(of:나 같은 신입사원을 돕기 위해, 여기 주로 애플의 문서에서 인용한 작업 예가 있다.- https://developer.apple.com/documentation/swift/2885064-type

doubleNum = 30.1

func printInfo(_ value: Any) {
    let varType = type(of: value)
    print("'\(value)' of type '\(varType)'")
}

printInfo(doubleNum)
//'30.1' of type 'Double'

나는 여기서 다른 몇 가지 답을 시도해 보았지만, 밀레이지는 그 밑에 있는 물체가 무엇인지에 대해 매우 잘 알고 있는 것 같다.

그러나 다음 작업을 수행하여 객체의 Object-C 클래스 이름을 가져올 수 있는 방법을 찾았습니다.

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for

다음은 사용 방법의 예입니다.

let now = NSDate()
println("what is this = \(now?.superclass as AnyObject!)")

이 경우 NSDate가 콘솔에 인쇄됩니다.

다른 사람에게도 통할 수 있는 해결책을 찾았습니다.값에 액세스하기 위해 클래스 메서드를 만들었습니다.이것은 NSObject 서브클래스에 대해서만 동작합니다.하지만 적어도 깨끗하고 정돈된 해결책이다.

class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}

Swift 1.2를 탑재한 최신 XCode 6.3에서는 이 방법밖에 없었습니다.

if view.classForCoder.description() == "UISegment" {
    ...
}

이 답변의 대부분은 최신 Swift에서 작동하지 않습니다(작성 시 X코드 7.1.1).

은 '만들다'를 입니다.Mirror과 같이단순합니다.클래스 이름의 경우 다음과 같이 단순합니다.

let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description

추가 에서 얻을 .Mirror자세한 것은, http://swiftdoc.org/v2.1/type/Mirror/ 를 참조해 주세요.

Swift 버전 4:

print("\(type(of: self)) ,\(#function)")
// within a function of a class

감사합니다 @조슈아 댄스

Swift 4:

// "TypeName"
func stringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(describing: some) : String(describing: type(of: some))
    return string
}

// "ModuleName.TypeName"
func fullStringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(reflecting: some) : String(reflecting: type(of: some))
    return string
}

사용방법:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"

베타 5의 lldb에서는 다음 명령을 사용하여 객체의 클래스를 볼 수 있습니다.

fr v -d r shipDate

출력은 다음과 같습니다.

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940

expanded 명령어는 다음과 같은 의미를 가집니다.

Frame Variable 변수 )('프레임 변수-d run_target 타입 (다이나믹 타입)

"프레임 변수"를 사용하여 변수 값을 출력하면 코드가 실행되지 않습니다.

는 자체 개발 수업(또는 당신이 접근할 수 있는 수업)을 위한 해결책을 찾았다.

오브젝트 클래스 정의 내에 다음 계산 속성을 배치합니다.

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}

이제 다음과 같이 오브젝트의 클래스 이름을 호출할 수 있습니다.

myObject.className

기능은 클래스 정의가 원하는 클래스와 정확히 동일한 이름의 파일 내에서 이루어지는 경우에만 작동합니다.

이것은 일반적인 경우이기 때문에 대부분의 경우 위의 답변이 해당됩니다.그러나 특별한 경우에는 다른 해결책을 찾아야 할 수도 있습니다.


클래스(파일) 자체에 클래스 이름이 필요한 경우 다음 행을 사용할 수 있습니다.

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

어쩌면 이 방법이 밖에 있는 사람들에게 도움이 될지도 몰라.

위의 Klass와 Kevin Ballard의 답변과 코멘트를 바탕으로 저는 다음과 같이 하겠습니다.

println(_stdlib_getDemangledTypeName(now).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon?).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon!).componentsSeparatedByString(".").last!)

println(_stdlib_getDemangledTypeName(myvar0).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar1).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar2).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar3).componentsSeparatedByString(".").last!)

다음과 같이 출력됩니다.

"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"
let i: Int = 20


  func getTypeName(v: Any) -> String {
    let fullName = _stdlib_demangleName(_stdlib_getTypeName(i))
    if let range = fullName.rangeOfString(".") {
        return fullName.substringFromIndex(range.endIndex)
    }
    return fullName
}

println("Var type is \(getTypeName(i)) = \(i)")

임의 값 유형의 유형 이름을 인쇄할 수 있는 일반적인 방법은 없는 것 같습니다.다른 사용자가 지적한 바와 같이 클래스인스턴스에 대해서는value.className그러나 원시 값의 경우 실행 시 유형 정보가 사라집니다.

를 들어, 이렇게 입력하는 것 .1.something()Intsomething ( 수 . (하다)를 사용해도 i.bridgeToObjectiveC().className__NSCFNumber실제로는 그런 타입이 아니다i 호출의 때것). -- Objective-C 함수 호출의 경계를 넘었을 때 변환됩니다

틀렸음을 증명해 주셨으면 합니다만, 타입 체크는 모두 컴파일시에 행해지는 것 같습니다.또, C++(RTTI가 무효가 되어 있는 것)와 같이, 많은 타입 정보가 런타임에 없어집니다.

이렇게 하면 개체 또는 개체 정의가 속한 모듈 또는 중첩된 모듈을 고려하여 일관된 유형의 유형 문자열을 얻을 수 있습니다.Swift 4.x에서 동작합니다.

@inline(__always) func typeString(for _type: Any.Type) -> String {
    return String(reflecting: type(of: _type))
}

@inline(__always) func typeString(for object: Any) -> String {
    return String(reflecting: type(of: type(of: object)))
}

struct Lol {
    struct Kek {}
}

// if you run this in playground the results will be something like
typeString(for: Lol.self)    //    __lldb_expr_74.Lol.Type
typeString(for: Lol())       //    __lldb_expr_74.Lol.Type
typeString(for: Lol.Kek.self)//    __lldb_expr_74.Lol.Kek.Type
typeString(for: Lol.Kek())   //    __lldb_expr_74.Lol.Kek.Type

원하는 것은 아니지만 다음과 같이 변수 유형을 Swift 유형에 대해 확인할 수도 있습니다.

let object: AnyObject = 1

if object is Int {
}
else if object is String {
}

예를들면.

Xcode 7.3.1, Swift 2.2:

String(instanceToPrint.self).componentsSeparatedByString(".").last

언급URL : https://stackoverflow.com/questions/24006165/how-do-i-print-the-type-or-class-of-a-variable-in-swift

반응형