Swift 将任意对象强制转换为T

Swift 将任意对象强制转换为T,swift,Swift,代码: 通过测试: class User { class var BoolProperty: Bool { get { var anyObject: AnyObject? = getValue("BoolProperty") if let value = anyObject as? Bool { return value } else

代码:

通过测试:

class User
{
    class var BoolProperty: Bool
    {
        get {
            var anyObject: AnyObject? = getValue("BoolProperty")

            if let value = anyObject as? Bool {
                return value
            }
            else {
                return false
            }
        }
        set(value) {
            setValue("BoolProperty", value: value)
        }
    }

    private class func getValue(key: String) -> AnyObject?
    {
        var store = NSUserDefaults.standardUserDefaults();
        return store.objectForKey(key) as AnyObject?
    }
}
但以下代码未通过相同的测试,该测试使用t代替Bool进行强制转换:

class UserTests: XCTestCase
{
    func testFields()
    {
        User.BoolProperty = true
        var result = User.BoolProperty
        XCTAssertEqual(true, result)
    }
}
类用户
{
类变量BoolProperty:Bool
{
得到{
return get(“BoolProperty”,defaultValue:false)
}
设置(值){
设置值(“BoolProperty”,值:value)
}
}
私有类func getValue(键:String)->AnyObject?
{
var store=NSUserDefaults.standardUserDefaults();
是否将store.objectForKey(key)作为AnyObject返回?
}
私有类func get(键:String,默认值:T)->T
{
var anyObject:anyObject?=getValue(键)
如果let value=anyObject as?T{
返回值
}
否则{
返回默认值
}
}
}
似乎出于某种原因,
如果let value=anyObject as?T
在对T进行强制转换时始终返回false


在C中,这是一个处理非类型集合的经典示例,我想知道在Swift中实现这一点的正确方法是什么。

问题是,
NSNumber
不是
Bool
。它看起来像一个
Bool
,可以转换成
Bool
,但它实际上是一种不同的类型。您的
anyObject
实际上是一个
NSNumber
,并要求它成为
as?T
其中
T
Bool
太远。这仍然可能是一个编译器错误,因为它应该与泛型相同,但这就是问题所在

您需要将泛型函数专门化为
NSNumber

class User
{
    class var BoolProperty: Bool
    {
        get {
            return get("BoolProperty", defaultValue: false)
        }
        set(value) {
            setValue("BoolProperty", value: value)
        }
    }

    private class func getValue(key: String) -> AnyObject?
    {
        var store = NSUserDefaults.standardUserDefaults();
        return store.objectForKey(key) as AnyObject?
    }

    private class func get<T>(key: String, defaultValue: T) -> T
    {
        var anyObject: AnyObject? = getValue(key)

        if let value = anyObject as? T {
            return value
        }
        else {
            return defaultValue
        }
    }
}
也许还是值得打开一个雷达。它不应该在使用和不使用泛型的情况下表现出不同的行为

也就是说,部分问题在于使用
AnyObject
Bool
不是
AnyObject
。这是一个
Any
。当您尝试将其分配给
AnyObject
时,它将转换为
NSNumber
。我不知道这方面的任何文件;我是在操场上根据经验计算出来的。比较a:AnyObject=false和a:Any=false的结果

理论上,这应该解决所有问题:

get {
return Bool(get("BoolProperty", defaultValue: NSNumber(bool: false)))
}

但它目前会使编译器崩溃。

问题在于
NSNumber
不是
Bool
。它看起来像一个
Bool
,可以转换成
Bool
,但它实际上是一种不同的类型。您的
anyObject
实际上是一个
NSNumber
,并要求它成为
as?T
其中
T
Bool
太远。这仍然可能是一个编译器错误,因为它应该与泛型相同,但这就是问题所在

您需要将泛型函数专门化为
NSNumber

class User
{
    class var BoolProperty: Bool
    {
        get {
            return get("BoolProperty", defaultValue: false)
        }
        set(value) {
            setValue("BoolProperty", value: value)
        }
    }

    private class func getValue(key: String) -> AnyObject?
    {
        var store = NSUserDefaults.standardUserDefaults();
        return store.objectForKey(key) as AnyObject?
    }

    private class func get<T>(key: String, defaultValue: T) -> T
    {
        var anyObject: AnyObject? = getValue(key)

        if let value = anyObject as? T {
            return value
        }
        else {
            return defaultValue
        }
    }
}
也许还是值得打开一个雷达。它不应该在使用和不使用泛型的情况下表现出不同的行为

也就是说,部分问题在于使用
AnyObject
Bool
不是
AnyObject
。这是一个
Any
。当您尝试将其分配给
AnyObject
时,它将转换为
NSNumber
。我不知道这方面的任何文件;我是在操场上根据经验计算出来的。比较a:AnyObject=false和a:Any=false的结果

理论上,这应该解决所有问题:

get {
return Bool(get("BoolProperty", defaultValue: NSNumber(bool: false)))
}

但它目前会使编译器崩溃。

谢谢。我已经使用NSString存储字符串值,NSNumber存储布尔值。谢谢。我使用NSString存储字符串值,NSNumber存储布尔值,这一方案现在可以在Xcode6-Beta6中使用。这一方案现在可以在Xcode6-Beta6中使用