Swift泛型中与Java任意类型<?>相对应的是什么?

6
在Java中,有时可以使用泛型而不必关心实际类型。在Swift中是否可以这样做?
例如,MyClass<AnyObject>与Java中的MyClass<?>不同,我希望它们能够以相同的方式工作。
还有其他方法吗?

我还没有找到使用通配符的情况,我相信Swift不需要它。你有这种情况吗?最相似的东西可能是MyClass<Any>,其中Any确实是任何类型(类、结构体、枚举、类型、函数、元组等),但再次说一遍,它可能就是通配符的作用,我无法完全记住它在Java中是如何工作的。 - Kametrixom
我正在尝试使用 class MoviesAPIRequest: APIRequest<Movie> 实例调用方法 func executeRequest(request: APIRequest<Any>),但是我得到了一个编译错误,提示“无法将类型为MoviesAPIRequest的值转换为预期的参数类型APIRequest<Any>”。 - Cosmin
2个回答

3

介绍一个类型参数;编译器将允许它接受任何类型。尝试:

func executeRequest<T> (request: APIRequest<T>) {
 // ...
}

例如:

class APIRequest<T> {}
class Movie {}
class MovieRequest : APIRequest<Movie> {}
let m = MovieRequest()
//print(m)

func executeRequest<T> (request: APIRequest<T>) {
    print(request)
}

executeRequest(m)

引入类型参数可以使代码更明确,更好地匹配问题域。例如,在您的情况下,您肯定不能对任何东西进行API请求;您可以在资源上进行API请求,比如说一个Resource。
protocol Resource {}
class Movie : Resource {}
class Song : Resource {}

class APIRequest<T:Resource> { /* ... */ }

func executeRequest<T:Resource> (request: APIRequest<T>) { /* ... */ } 

3
在Swift中没有等同的概念。Swift中的泛型与Java中的不同,因此使用情况也有所不同。在Swift中,泛型非常适合制作通用实用程序构造和函数。如果您考虑围绕泛型设计具有预期继承的类,请注意您的设计并考虑替代方案。这可能会很有挑战性。两种语言存在根本的差异,因此尝试保持代码的平衡可能会很困难。根据您问题的具体情况,以下是一些可能的选择:
// start with a common protocol
protocol Requestable {
    func execute()
    func processData(input: Any)
}


// protocol with type constraint
protocol APIRequest : Requestable {
    typealias ContentType
    var content : ContentType { get }
    func processInput(input: ContentType)
}


extension APIRequest {
    func processData(input: Any) {
        if let input = input as? ContentType {
            processInput(input)
        } else {
            // probably should throw an error here
        }
    }
}


// Either define a Generic function to execute with a specific type
func executeRequest<RequestType:APIRequest>(request: RequestType) {
    request.execute()
}


// Or define a function taking a protocol conforming type
func executeRequest(request: Requestable) {
    request.execute()
}


// process the data with a specific request and input
func processRequest<RequestType:APIRequest>(request: RequestType, input: RequestType.ContentType) {
    request.processInput(input)
}


// process the data with input of arbitrary type
func processRequest(request: Requestable, data: Any) {
    request.processData(data)
}


class Movie {
}


class MovieRequest : APIRequest {
    var content : Movie

    init(movie: Movie) {
        self.content = movie
    }

    func execute() {
        // do something here
    }

    func processInput(input: Movie) {
        // do something with the movie input
    }
}

let movieRequest = MovieRequest(movie: Movie())
executeRequest(movieRequest)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接