如何产生一个泛型类型的零 [英] How to produce a nil of a generic type

查看:81
本文介绍了如何产生一个泛型类型的零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想声明一个通用类,它持有/获得类型为 Any 的变量,但会根据请求将此变量转换为给定类型。就像这样

  class A< T> {
var o:NSObject!
var k:String!
var v:T {
get {return o.value(forKeyPath:k)as! T}
set {o.setValue(newValue,forKeyPath:k)}
}
}

我想这样做,以便当 o.value(forKeyPath:k) nil T 可以存放 nil (它是 ExpressibleByNilLiteral T ), v 返回 nil >)。事实上,它因为!而崩溃。是否有可能做到这一点?



试图在这个看起来像这样(建议


  class A< T> {
var o:NSObject!
var k:String!
var v:T {
get {
let x = o.value(forKeyPath:k)
如果让E = T.self为? ExpressibleByNilLiteral.Type {
如果让x = x {return x as! T}
让n:T =< nil类型T> < ----不确定在这里放什么
返回n
}其他{
return x as! T
}
}
set {o.setValue(newValue,forKeyPath:k)}
}
}

但我不确定如何使它正常工作。 解决方案

不知道为什么,但这实际上有效

  func cast< T>(_ v:Any?) - > T {
如果让E = T.self为? ExpressibleByNilLiteral.Type {
如果让v = v {
返回v as! T
} else {
返回E.init(nilLiteral:())as! T
}
} else {
return v as! T
}
}

我以为我已经试过了,工作...无论如何,现在我们可以用 cast 代替所有作为!调用,当我们不想崩溃时 nil ,如果我们正在投射的类型可以接受它,例如在我的问题的getter。


I would like to declare a generic class which holds/obtains a variable of type Any?, but casts this variable to a given type, when requested. Something like this

class A<T> {
    var o: NSObject!
    var k: String!
    var v: T {
        get { return o.value(forKeyPath: k) as! T }
        set { o.setValue(newValue, forKeyPath: k) }
    }
}

I would like to this to work so that when o.value(forKeyPath: k) is nil and T can hold a nil (it is ExpressibleByNilLiteral), v returns nil (of type T). As it is, it crashes because of the as!. Is it possible to do this?

An attempted crack at this looks like this (suggested by How to make a computed property of a generic class depend on the class constraints)

class A<T> {
    var o: NSObject!
    var k: String!
    var v: T {
        get { 
            let x = o.value(forKeyPath: k)
            if let E = T.self as? ExpressibleByNilLiteral.Type {
                if let x = x { return x as! T }
                let n: T = <nil of type T> <---- not sure what to put here
                return n
            } else {
                return x as! T 
            }
        }
        set { o.setValue(newValue, forKeyPath: k) }
    }
}

but I am not sure how to make it work.

解决方案

Not sure why, but this actually works

func cast<T>(_ v: Any?)->T {
    if let E = T.self as? ExpressibleByNilLiteral.Type {
        if let v = v {
            return v as! T
        } else {
            return E.init(nilLiteral: ()) as! T
        }
    } else {
        return v as! T
    }
}

I thought I already tried this and it did not work... Anyway, now we can substitute all as! calls with cast when we do not want to crash on nil, if the type we are casting to can take it, e.g. in the getter of my question.

这篇关于如何产生一个泛型类型的零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆