如何在 Swift 中判断变量的类型
Posted
技术标签:
【中文标题】如何在 Swift 中判断变量的类型【英文标题】:How to determine the type of a variable in Swift 【发布时间】:2014-06-07 03:45:51 【问题描述】:在 Swift 中有确定变量类型的函数吗?我想在 Python 中可能会有类似type()
之类的东西。
我想要一种方法来判断变量是 Swift 中的 Foundation 对象还是 C 变量。就像 NSString vs String,或者 NSArray vs array。这样我就可以在控制台中将其注销并清楚地看到它是什么。
例如,我想知道为下面的第一个array
推断的类型:
var array = [1,2,3] // by default NSArray or array?
var array:[Int] = [1,2,3]
var array:NSArray = [1,2,3]
var array:Array<Any> = [1,2,3]
我已经看到了判断 given 变量是否是 this question 中的一种 given 类型的答案,但我会说它与我想要的完全不同问。
【问题讨论】:
我不知道,但你可以自己滚下来? 我已编辑问题以使我的陈述更清晰 您能否举例说明您想在哪些代码类型中使用这些知识?如果类型在编译时已知,您可能可以使用泛型函数,例如func show<T>(x:T) println("\(x) is of type \(T)"
。如果在编译时不知道它,我不确定这是否可能,因为 C 值似乎没有必要的运行时元数据。 (遗憾的是,我无法亲自尝试,因为 Apple 仍未批准我的开发者帐户。)
我不同意将这个问题作为How to get Type of an Object in Swift 的副本来结束。尽管所写的问题是适当的重复,但现实情况是所有答案,包括已接受的答案,仅用于确定值是否属于给定类型。除非另一个问题的提问者不想接受那个答案,否则我认为他们将问题缩小到检查一个值是否属于给定类型是合理的,使其与这个问题不同。
我同意,确定给定类型和直接确定类型是不一样的
【参考方案1】:
您可以使用.dynamicType
属性获取对值的类型对象的引用。这相当于Python的type()
函数,提到了in the Swift documentation under Language Reference: Types: Metatype Type。
var intArray = [1, 2, 3]
let typeOfArray = intArray.dynamicType
使用这个类型对象,我们可以创建一个相同数组类型的新实例。
var newArray = typeOfArray()
newArray.append(5)
newArray.append(6)
println(newArray)
[5, 6]
我们可以通过尝试附加一个浮点数来看到这个新值属于同一类型 ([Int]
):
newArray.append(1.5)
error: type 'Int' does not conform to protocol 'FloatLiteralConvertible'
如果我们导入 Cocoa 并使用混合类型的数组字面量,我们可以看到创建了一个 NSArray
:
import Cocoa
var mixedArray = [1, "2"]
let mixedArrayType = mixedArray.dynamicType
var newArray = mixedArrayType()
var mutableArray = newArray.mutableCopy() as NSMutableArray
mutableArray.addObject(1)
mutableArray.addObject(1.5)
mutableArray.addObject("2")
println(mutableArray)
(1, "1.5", 2)
但是,目前似乎没有任何通用方法可以生成类型对象的字符串描述,因此这可能无法满足您所询问的调试角色。
派生自NSObject
的类型确实有一个.description()
方法,正如in SiLo's answer 所使用的那样,
println(mixedArrayType.description())
__NSArrayI
但是这在 Swift 的内置数组等类型上不存在。
println(typeOfArray.description())
error: '[Int].Type' does not have a member named 'description'
【讨论】:
顺便说一句:除了obj.description()
,您始终可以使用String(obj)
(如果可用,这将使用描述)。
.dynamicType 现在已弃用。 typeof 等价物现在是 type(of: myvariable)
@logicor 感谢您的信息。想建议对这篇文章进行编辑(这样你就可以得到添加的功劳)?如果没有,我稍后会自己编辑。【参考方案2】:
选项+单击您要检查的变量。
【讨论】:
【参考方案3】:这是可能的,虽然它不一定那么容易或有用:
func getClassName(obj : AnyObject) -> String
let objectClass : AnyClass! = object_getClass(obj)
let className = objectClass.description()
return className
let swiftArray = [1, 2, 3]
let swiftDictionary = ["Name": "John Doe"]
let cocoaArray : NSArray = [10, 20, 30]
var mutableCocoaArray = NSMutableArray()
println(getClassName(swiftArray))
println(getClassName(swiftDictionary))
println(getClassName(cocoaArray))
println(getClassName(mutableCocoaArray))
输出:
_TtCSs22ContiguousArrayStorage00007F88D052EF58
__NSDictionaryM
__NSArrayI
__NSArrayM
你最好在 Swift 中使用 is
和 as
关键字。许多基础类使用类簇(如您所见,__NSArrayI
(不可变)和__NSArrayM
(可变)。
注意有趣的行为。 swiftArray
默认使用 Swift Array<Int>
,而 swiftDictionary
默认使用 NSMutableDictionary
。对于这种行为,我不会真正依赖某种类型的东西(首先检查)。
【讨论】:
为什么不直接使用 object_getClassName?【参考方案4】:有人在上面提到了这一点,但我认为它值得作为答案而不是评论来展示。你现在可以简单地使用 type(of: ___):
var red, green, blue: Double
print(type(of: green))
产量
双
【讨论】:
【参考方案5】:我在调试过程中使用断点,但是如果您需要在运行时检查它们是否匹配某个类型,那么drawag是正确的
您可以做的另一件事是使用断言测试数据类型,这仅适用于调试,但使用断言您可以设置条件,如果遇到应用程序崩溃
也许像assert(let tArray == oldArray as? NSArray[] //if not NSArray app crashes)
【讨论】:
这会检查 if var 是 specific 类型,而不是 what 类型 is我>。感谢您的意见。以上是关于如何在 Swift 中判断变量的类型的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swift 的扩展中声明 NSLayoutConstraint 类型的变量
如何检查在 swift 中声明的 UnsafeMutablePointer<ObjCBool> 类型的变量的值? [复制]