有没有办法在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
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我正在寻找一种方法来显示变量"很快"是类型ImplicitlyUnwrappedOptional<NSDate>,或至少NSDate!.
Kla*_*aas 366
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)")
Run Code Online (Sandbox Code Playgroud)
哪个输出:
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>
Run Code Online (Sandbox Code Playgroud)
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))")
Run Code Online (Sandbox Code Playgroud)
并将此作为输出:
TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String
Run Code Online (Sandbox Code Playgroud)
原始答案:
在Xcode 6.3之前_stdlib_getTypeName获得变量的错位类型名称.Ewan Swick的博客文章有助于破译这些字符串:
例如_TtSi代表Swift的内部Int类型.
aka*_*kyy 45
编辑: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
Run Code Online (Sandbox Code Playgroud)
试着打电话YourClass.self和yourObject.dynamicType.
参考:https://devforums.apple.com/thread/227425.
Evg*_*nii 31
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>"
Run Code Online (Sandbox Code Playgroud)
Hai*_*ezu 30
这是你在找什么?
println("\(object_getClassName(now))");
Run Code Online (Sandbox Code Playgroud)
它打印"__NSDate"
更新:请注意,这似乎不再适用于Beta05
Mat*_*gen 23
我目前的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).")
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
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.
Run Code Online (Sandbox Code Playgroud)
kid*_*ing 18
从使用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"
Run Code Online (Sandbox Code Playgroud)
Lea*_*ros 17
您仍然可以通过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'
Run Code Online (Sandbox Code Playgroud)
如果要获取基元的类型,则必须使用bridgeToObjectiveC().例:
var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber
Run Code Online (Sandbox Code Playgroud)
mxc*_*xcl 13
我好运:
let className = NSStringFromClass(obj.dynamicType)
Run Code Online (Sandbox Code Playgroud)
Har*_*war 12
Xcode 8 Swift 3.0使用类型(:)
let className = "\(type(of: instance))"
Run Code Online (Sandbox Code Playgroud)
use*_*037 10
let type : Type = MyClass.self //Determines Type from Class
Run Code Online (Sandbox Code Playgroud)
let type : Type = type(of:self) //Determines Type from self
Run Code Online (Sandbox Code Playgroud)
let string : String = "\(type)" //String
Run Code Online (Sandbox Code Playgroud)
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))
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个静态函数,它将参数作为类型的对象,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()
Run Code Online (Sandbox Code Playgroud)
输出是:
使用Cocoa(而非CocoaTouch)时,可以将className属性用于NSObject子类的对象。
println(now.className)
Run Code Online (Sandbox Code Playgroud)
此属性不适用于普通的Swift对象,这些对象不是NSObject的子类(实际上,Swift中没有根ID或对象类型)。
class Person {
var name: String?
}
var p = Person()
println(person.className) // <- Compiler error
Run Code Online (Sandbox Code Playgroud)
在CocoaTouch中,目前尚无法获取给定变量类型的字符串描述。对于Cocoa或CocoaTouch中的原始类型,也不存在类似的功能。
Swift REPL能够打印出包括其类型的值的摘要,因此将来有可能通过API进行这种自省。
编辑:dump(object)似乎可以解决问题。
最佳答案没有使用新方法的工作示例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'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
203468 次 |
| 最近记录: |