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中使用