Swift operator "is" with the type stored in the variable

This piece of code works as expected. "integer is int" is output.

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

I want to use the is operator the same way I can use the isKindOfClass method - with a class (or rather a type) stored in a variable. It will look like this:

 let integer = Int() let intType : Any = Int.self if integer is intType { println("Integer is int") } else { println("Integer is not int") } 

Unfortunately, this causes an error: Use of undeclared type 'IntType' .

IntType in an if condition has even a different color (if you insert it into the playing field) than in other places in the source code, assuming that (as stated in the error message) it is treated as a class name (for example, IntType will be a class). But this is not so. Does this mean that the is operator cannot be used with variables on the right side?

I want to use the is operator because it can compare not only classes, but also other types.

How to check if the type I expect matters?


I found a dirty solution, but it is really far from reliable ...

 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") } 

Works fine, but be careful - because this is also true:

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

Is there a better way?


Well, I’ll explain again what I want to achieve. I have an object that manages instances of instances of a generic class. At some point, I need to select one of these instances of a generic class based on the generic type. Example:

 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 

I currently have a ToolInfo struct, because as far as I know, it is impossible to get the type passed to <> when instantiating a generic class object. But I still can't compare it.

+8
types swift
source share
2 answers

Does this mean that the operator cannot be used with variables on the right side?

Correctly. The right side is must be hardcoded at compile time.

If you don't need polymorphism, and types are class types, you can use === to compare the instance dynamicType with the class type. This is the only way to get type-in-variable on the right side of something in pure Swift.

+6
source share

Here is my experiment with a container of type enum (sorry, it was written struct by mistake in the comment earlier):

 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 } 

You can do something similar in your project.

-2
source share

All Articles