6

在 Java 中,您有时可以使用泛型而不关心实际类型。你能在 Swift 中做到这一点吗?

例如MyClass<AnyObject>不像MyClass<?>在 Java 中那样工作。在我希望它能够正常工作。

还有其他方法吗?

4

2 回答 2

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)
于 2015-11-20T17:03:28.053 回答
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)

类型参数的引入允许更明确并更好地匹配问题域。例如,就您而言,您肯定不能做APIRequest任何事情;你可以做一个APIRequest,比如说,一个Resource

protocol Resource {}
class Movie : Resource {}
class Song : Resource {}

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

func executeRequest<T:Resource> (request: APIRequest<T>) { /* ... */ } 
于 2015-11-24T19:17:39.220 回答