swift中的通用问题

时间:2014-11-12 06:47:31

标签: generics swift

我已经定义了这样的协议:

public protocol JSONConvertible {
    typealias T

    class func fromDictionary(dict: NSDictionary) -> T?
    class func fromArray(arr: NSArray) -> Array<T>
}

fromDictionary将字典转换为对象,例如User,而fromArray将使用fromDictionary将NSArray转换为Array。

我想做的是提供一个BasicObject,它为fromArray提供默认实现,如:

public class BasicObject<T>: JSONConvertible {

    public class func fromDictionary(dict: NSDictionary) -> T? {
        return nil
    }

    public class func fromArray(arr: NSArray) -> Array<T> {
        var result = Array<T>()

        for obj in arr {
            if let object: T = self.fromDictionary(obj as NSDictionary) {
                result.append(object)
            }
        }

        return result
    }

}

然后User类将继承自BasicObject。

然而,当我在Java中这样做时,它告诉我类也必须是通用的:

public class User: BasicObject<User> {}

然后代码变为:

public class User<User>: BasicObject<User> {}

首先这看起来很奇怪,其次当我初始化一个对象时,它会是:

var user = User<User>()

并且无法传递编译(错误:无法构造,因为它没有可访问的初始化程序)。

那么我该怎样做才能实现我的目的呢?感谢。

2 个答案:

答案 0 :(得分:0)

错误是因为我在测试用例中启动它并且init()不是公共的。

Also User<User> can be anything like User<Int>()

有类型的解决方案:

typealias user = User<Int>

然后你可以用:

初始化你的对象
user()

However the User<Int> brings unnecessary <Int> and it looks really weird.

答案 1 :(得分:0)

我的建议如下:

protocol JSONConvertible {
    class func fromDictionary(dict: NSDictionary) -> Self?
}

func objectsFromArray<T: JSONConvertible>(arr: NSArray) -> [T] {
    var result = [T]()
    for elem in arr {
        let dict = elem as NSDictionary
        if let obj = T.fromDictionary(dict) {
            result.append(obj)
        }
    }
    return result
}

class User: JSONConvertible {
    class func fromDictionary(dict: NSDictionary) -> Self? {
        return nil
    }
}
  1. fromDictionary方法应返回Self?,如图所示。
  2. 不要费心将fromArray放入您的协议中。由于Swift的泛型的限制,返回[Self]并不能很好地工作。 (尝试一下,你会发现原因。)因此,我将fromArray作为一个名为objectsFromArray的全局函数。如果这对您来自Java世界感到不满,请记住,Swift有许多全局函数可用于泛型,例如containsprefixjoin等。由于Swift类型系统存在某些限制,因此是全局函数而不是方法。
  3. 不要打扰创建基类。我知道这是你对Java的本能,而且我的也是来自C#,但它在这里效果不好。