我想将定义为RealmOptional
的类型转换为Int
或Float
,具体取决于分配给通用的类型。但是,当我尝试使用switch
语句分发它们时,结果发现不是RealmOptional<Int>()
而是RealmOptional<Float>()
被归类为Int
个案例。例如,
switch value { // value is of type AnyObject?
case is String:
cell.valueLabel.text = value as? String
case is Int:
// RealmOptional<Float> are executed here
let v = value as! Int
cell.valueLabel.text = String(v) // Float is now treated as Int
case is Double:
print("double") // not printed at all
cell.valueLabel.text = String(value!)
default:
break
}
为什么RealmOptional<Float>()
在这里表现为Int
?如何将文本正确设置为value
?
答案 0 :(得分:6)
让我们假设您的RealmOptional<Float>()
变量名为myFloat
。然后,使用getm作为RealmOptional:s(参见this git entry for Realm)基础值,.value
,而不是检查RealmOptional本身:
var value = myFloat.value // value variable now of type Float
下面说明AnyObject?
开关不按预期行事的原因:
来自Apples Language Guide - Type Casting:
为Any和AnyObject输入类型
Swift提供了两种特殊类型的别名,用于处理非特定的别名 类型:
- AnyObject可以表示任何类类型的实例。
- 任何可以表示任何类型的实例,包括函数类型。
因此,AnyObject
类型可以保存任何类类型的实例,但Swift中的基本数字类型(Int
,Double
等)不是类类型,而是类型结构类型。
在您的示例中的switch
中,AnyObject
实例未被推断,但强制转换到第一个可能成功的向下广播,这将是case
您的任何内容把最顶层的数字类型。因此,如果您更改交换机中case
:s的顺序,则转换将更改。
let value: AnyObject? = 30.0
// try change the order
switch value {
case is String: print("string");
case is Float: print("float"); // hits `Float` downcast first -> prints float
case is Int: print("int");
default: print("other")
}
现在,您可以将AnyObject
投射到NSNumber
(类实例),并从那里继续。来自Working with Cocoa Data Types documentation:
Swift数值结构类型的实例,例如Int,UInt, Float,Double和Bool不能用AnyObject类型表示, 因为AnyObject只表示类类型的实例。然而, 当启用桥接到基础时,Swift数值可以是 分配给AnyObject类型的常量和变量作为桥接 NSNumber类的实例。
但请注意,NSNumber
与Swift数字类型(Int
,Double
等)根本不同,前者包含任何类型的数字,并允许我们转换此数字到不同类型的数字类型。但是,我们无法轻易推断应该将特定NSNumber
实例转换为哪种类型,但我们可以实现自己的(不那么漂亮)规范,如何将不同的NSNumber
推断为不同的快速基本数字类型。
但是,在继续进行NSNumber
黑客攻击之前
从上面看,核心问题是您的value
属性属于AnyObject?
类型。您能否发布导致value
类型为AnyObject?
的代码。如果使用RealmOptional的getter(因此无需将Int
强制转换为Float
),可能会转换为RealmOptional<T>()
,AnyObject?
等等,如果没有必要的话。 p>
答案 1 :(得分:0)
我发现这与Realm无关;它与Swift有关。在Swift中传递switch
中的浮动对象时,它不仅会在is Float
中,而且会在is Int
中,因为浮点数可以转换为Int
好。
例如,下面的代码没有经过is Float
条件,因为它在is Int
中被捕获:
let value: AnyObject? = 30.0
switch value {
case is String: print("string");
case is Int: print("int");
case is Float: print("float");
default: print("other")
}
这就是RealmOptional<Float>()
is Int
中出现Int
的原因。
我仍然不知道如何处理此问题,因为is Float
类型的对象被Float
捕获,而is Int
类型的对象被捕获在dist/something
。也许有人可以加入......