簡體   English   中英

在 Swift 中切換泛型類中的泛型類型

[英]Switch over the generic type in a generic class in Swift

我最近嘗試為 iOS 10 中的Measurement類型編寫一個擴展,它在通用UnitType的類型上切換UnitType 我想要做的是根據單位類型在UILabel上指定不同的字符串輸出。 我的目標是簡化用法

我想出的解決方案為每種類型的泛型定義一個方法,如下所示:

func localizedDescription(for length: Measurement<UnitLength>) -> String {
    // some code
}

func localizedDescription(for speed: Measurement<UnitSpeed>) -> String {
    // some code
}

// etc.

我真正想要的是不同的東西,但我無法讓它發揮作用。 也許你可以,或者這是 Swift 到目前為止的限制。 我准備了一個 Swift Playground 來詳細解釋這一點。

示例 Playground 代碼

這是應該復制這種情況的代碼:

import Foundation

//: Example Classes

class GenericType: NSObject {
    // some code

    var value: Double {
        preconditionFailure("Must be overridden in subclasses.")
    }
}
class GenericSubType1: GenericType {
    override var value: Double { return 5 }
}
class GenericSubType2: GenericType {
    override var value: Double { return 10 }
}

// Note that the class is predefined in a different place, so I can't use the body directly.
class SomeClass<T: GenericType> {
    var valueType: T
    init(valueType: T) {
        self.valueType = valueType
    }
}

Switch-Case 擴展

這是我使用 switch-case 的一種方法

//: Switch-Case in Extension

extension SomeClass {
    var localizedDescription: String {
        switch T.self { // `type(of: T)` doesn't work, `T` does neither
        case is GenericSubType1:
            return "\(valueType.value) times"

        case is GenericSubType2:
            return "\(valueType.value) people"

        default:
            preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
        }
    }
}

我在兩條case行中收到警告,其中指出:

從“T.Type”轉換為不相關的類型“GenericSubType1”總是失敗

我不確定為什么這會給我這個警告,我希望這能按預期工作。 有人可以解釋我嗎? 而且,你會如何最好地解決這種事情?

在寫這個問題時,我嘗試了一些其他的東西,可以想出以下解決方案:

//: Multiple Extensions

extension SomeClass where T: GenericSubType1 {
    var localizedDescription: String {
        return "\(valueType.value) times"
    }
}

extension SomeClass where T: GenericSubType2 {
    var localizedDescription: String {
        return "\(valueType.value) people"
    }
}

現在,當我運行以下代碼時,輸​​出符合預期:

SomeClass(valueType: GenericSubType1()).localizedDescription // => "5.0 times"
SomeClass(valueType: GenericSubType2()).localizedDescription // => "10.0 people"

不涉及 switch-case ,所以如果你能做到這一點,我很高興聽到你的回答。 但這可以作為擴展,所以我想分享一下。

如果你想在這種情況下使用開關,你有兩個選擇:

extension SomeClass {
    var localizedDescription: String {
        switch valueType {
        case is GenericSubType1:
            return "\(valueType.value) times"

        case is GenericSubType2:
            return "\(valueType.value) people"

        default:
            preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
        }
    }
}

或者

extension SomeClass {
    var localizedDescription: String {
        switch T.self {
        case is GenericSubType1.Type:
            return "\(valueType.value) times"

        case is GenericSubType2.Type:
            return "\(valueType.value) people"

        default:
            preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM