斯威夫特"是"存储在变量

时间:2015-08-06 14:18:04

标签: swift types

这段代码按预期工作。 "整数是int"打印在输出中。

let integer = Int()

if integer is Int {
    println("integer is int")
}
else {
    println("integer is not int")
}

我希望以与使用is方法相同的方式使用isKindOfClass运算符 - 将类(或更确切地说类型)存储在变量中。它看起来像这样:

let integer = Int()
let intType : Any = Int.self

if integer is intType {
    println("Integer is int")
}
else {
    println("Integer is not int")
}

不幸的是,这会产生错误:Use of undeclared type 'IntType'

IntType条件中的{p> if甚至有不同的颜色(如果将其粘贴到游乐场),而不是源代码中的其他位置,这表明(如错误消息所示)其被视为类名(如IntType将是一个类)。但它不是。这意味着is运算符不能与右侧的变量一起使用吗?

我想使用is运算符,因为它不仅可以比较类,还可以比较其他类型。

如何检查值是否具有我期望的类型?

我找到了肮脏的解决方案,但它远非可靠......

let integer = Int()
let intType : Any = Int.self

func ==(left: Any, right: Any) -> Bool {
    let leftString = "\(left)"
    let rightString = "\(right)"
    return leftString == rightString
}

if (integer.dynamicType as Any) == intType {
    println("true")
}
else {
    println("false")
}

工作完美,但要小心 - 因为这个也是如此:

if (integer.dynamicType as Any) == ("Swift.Int" as Any) {
    println("true")
}
else {
    println("false")
}

有更好的方法吗?

好的,我将进一步解释我想要实现的目标。我有管理泛型类实例的实例的对象。在某些时候,我需要根据泛型类型选择其中一个泛型类实例。示例:

class GenericClass<T> {}

struct ToolInfo {
    let tool : AnyObject
    let jobType : Any
}

class Manager {
    var tools = Array<ToolInfo>()

    func pickToolForTheJob(job : Any) -> AnyObject {
        return tools.magicMethodWhichReturnProperTool()
    }
}

let viewTool = GenericClass<UIView>()
let rectangleTool = GenericClass<CGRect>()

let manager = Manager()
manager.tools.append(ToolInfo(tool: viewTool, jobType: UIView.self))
manager.tools.append(ToolInfo(tool: rectangleTool, jobType: CGRect.self))

manager.pickToolForTheJob(UIView()) // i want to get viewTool here
manager.pickToolForTheJob(CGRect()) // i want to get rectangleTool here

目前我有ToolInfo结构,因为据我所知,在实例化泛型类对象时,不可能在<>中传递类型。但我还是无法比较它。

2 个答案:

答案 0 :(得分:6)

  

这意味着运算符不能与右侧的变量一起使用吗?

正确。 is的右侧必须在编译时进行硬编码。

如果您不需要多态,并且您的类型是类类型,则可以使用===将实例的dynamicType与类类型进行比较。这是你在纯Swift的右侧获得一个变量类型的唯一方法。

答案 1 :(得分:-2)

以下是我在enum类型容器中的实验(抱歉,在前面的评论中错误地写了struct):

enum TypeContainer {
    case SomeInt(Int)
    case SomeString(String)
    case SomeBool(Bool)

    init(int: Int) {
        self = .SomeInt(int)
    }

    init(string: String) {
        self = .SomeString(string)
    }

    init(bool: Bool) {
        self = .SomeBool(bool)
    }
}

let a = TypeContainer(string: "123")
let b = TypeContainer(int: 88)
let c = TypeContainer(bool: true)

switch a {
case .SomeInt(let i):
    println(i)
case .SomeString(let s):
    println(s)
case .SomeBool(let b):
    println(b)
default:
    break
}

你可以在你的项目中做这样的事情。