如何在Swift中将RealmOptional转换为Int或Float?

时间:2015-12-22 07:07:41

标签: ios swift realm

我想将定义为RealmOptional的类型转换为IntFloat,具体取决于分配给通用的类型。但是,当我尝试使用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

2 个答案:

答案 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中的基本数字类型(IntDouble等)不是类类型,而是类型结构类型。

在您的示例中的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数字类型(IntDouble等)根本不同,前者包含任何类型的数字,并允许我们转换此数字到不同类型的数字类型。但是,我们无法轻易推断应该将特定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。也许有人可以加入......