如何在Swift中打印变量的类型或类?

 momo左 发布于 2023-01-12 07:44

有没有办法在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 has no "description" method

在上面的例子中,我正在寻找一种方法来显示变量"很快"是类型ImplicitlyUnwrappedOptional,或至少NSDate!.

15 个回答
  • 编辑:Swift 1.2(Xcode 6.3)中引入了一个新toString功能.

    现在,您可以打印demangled类型使用任何类型的.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.selfyourObject.dynamicType.

    参考:https://devforums.apple.com/thread/227425.

    2023-01-12 07:46 回答
  • 这是你在找什么?

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

    它打印"__NSDate"

    更新:请注意,这似乎不再适用于Beta05

    2023-01-12 07:49 回答
  • 2016年9月更新

    Swift 3.0:使用type(of:),例如type(of: someThing)(因为dynamicType关键字已被删除)

    2015年10月更新:

    我将下面的示例更新为新的Swift 2.0语法(例如,现在println替换为).printtoString()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的博客文章有助于破译这些字符串:

    例如_TtSi代表Swift的内部Int类型.

    Mike Ash有一篇很棒的博客文章,涵盖了相同的主题.

    2023-01-12 07:50 回答
  • 我目前的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.
    

    2023-01-12 07:51 回答
  • 您仍然可以通过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
    

    2023-01-12 07:51 回答
  • 从使用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"
    

    2023-01-12 07:52 回答
  • 您可以使用反射来获取有关对象的信息.
    例如对象类的名称:

    var classname = reflect(now).summary
    

    2023-01-12 07:53 回答
  • 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>"
    

    2023-01-12 07:54 回答
  • 在Swift 3.0中,您可以使用type(of:),因为dynamicType关键字已被删除.

    2023-01-12 07:54 回答
  • 我好运:

    let className = NSStringFromClass(obj.dynamicType)
    

    2023-01-12 07:57 回答
  • 在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.将Type转换为String:

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

    2023-01-12 07:58 回答
  • Xcode 8 Swift 3.0使用类型(:)

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

    2023-01-12 07:58 回答
  • SWIFT 3

    使用最新版本的Swift 3,我们可以通过String初始化程序获得类型名称的漂亮描述.比如,例如print(String(describing: type(of: object))).哪里object 可以是实例变量,如数组,字典,a Int,a NSDate,自定义类的实例等.

    这是我的完整答案:在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()
    

    输出是:

    diccionary是Dictionary类型

    array的类型为Array

    numInt的类型为Int

    numFloat的类型为CGFloat

    numDouble的类型为Double

    classOne的类型为:ClassOne

    classTwo的类型为:ClassTwo

    现在是类型:日期

    lbl的类型:UILabel

    2023-01-12 07:59 回答
  • 使用Cocoa(而非CocoaTouch)时,可以将className属性用于NSObject子类的对象。

    println(now.className)
    

    此属性不适用于普通的Swift对象,这些对象不是NSObject的子类(实际上,Swift中没有根ID或对象类型)。

    class Person {
        var name: String?
    }
    
    var p = Person()
    println(person.className) // <- Compiler error
    

    在CocoaTouch中,目前尚无法获取给定变量类型的字符串描述。对于Cocoa或CocoaTouch中的原始类型,也不存在类似的功能。

    Swift REPL能够打印出包括其类型的值的摘要,因此将来有可能通过API进行这种自省。

    编辑dump(object)似乎可以解决问题。

    2023-01-12 07:59 回答
  • 最佳答案没有使用新方法的工作示例type(of:.所以为了帮助像我这样的新手,这里有一个很好的例子,主要来自Apple的文档 - 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'
    

    2023-01-12 08:02 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有