Próbuję mieć funkcję podjąć wkład ogólny, który jest zgodny zarówno do klasy, jak i protokołu w celu przetwarzania wartości, w których niektóre należą do klasy, a inne należą do delegata. Działa dobrze dla poszczególnych typów, ale nie dla tablicy typów (które są zgodne zarówno do Super Class, jak i Delegat). Zamiast tego kompilator rzuca błąd "Metoda instancji" PrintValues (dla :) ", wymaga, aby" pomiarowoClass "jest zgodny z" UNITDELEGET ""

Dodałem poniższy kod, który osiągnie znacznie więcej sensu. Wystarczy umieścić go w szybkim placu zabaw. Jeśli go uruchomisz, jak widać, że prawidłowo drukuje odległość użytkowników i kroki indywidualnie. Jeśli odrzuciłeś ostatnie kilka linii, ta sama funkcja nie może być używana z tablicą.

Moim celem jest móc przekazać tablicę typów, które są zgodne z UNITDELEGED i pomiarowąClass (AKA MeaserObject Typealias) i mają przetwarzane wartości. Chcę tablicy, ponieważ będę musiał mieć kilka różnych klas, które są zgodne z pomiarami.

protocol UnitDelegate: class{
    var units: [String: String] { get }
}

class MeasurementClass{
    var imperial: Double!
    var metric: Double!
    
    convenience init(imperial: Double, metric: Double){
        self.init()
        self.imperial = imperial
        self.metric = metric
    }
}

typealias MeasurementObject = MeasurementClass & UnitDelegate


class Distance: MeasurementObject{
    var units = ["imperial": "miles", "metric":"kms"]
}

class Steps: MeasurementObject{
    var units = ["imperial": "steps", "metric":"steps"]
}

class User{
    func printValues<T: MeasurementObject>(for type: T) {
        print("\(type.imperial!) \(type.units["imperial"]!) = \(type.metric!) \(type.units["metric"]!)")
    }
}

//This is what I'm trying to achieve in the for loop below
let distance = Distance(imperial: 30, metric: 48.28)
let steps    = Steps(imperial: 30, metric: 30)
let user     = User()
user.printValues(for: distance)
user.printValues(for: steps)


//let types = [distance, steps]
//
//for type in types{
//    user.printValues(for: type)
//}
0
Richard Witherspoon 21 listopad 2020, 01:50

1 odpowiedź

Najlepsza odpowiedź

Nie bezpośrednia odpowiedź na Twoje pytanie, ale wszystko, czego potrzebujesz, jest dodanie wyliczenia do przechowywania rodzaju pomiaru do swojej klasy i właściwości obliczeniowej w celu zwrócenia odpowiedniego słownika. Nie ma potrzeby używania protokołu, składu protokołu, klasy i / lub podklasy, aby wykonać to, co próbujesz zrobić:

struct AMeasurement {
    let imperial: Double
    let metric: Double
    let kind: Kind
    enum Kind { case distance, steps }
    var units: [String: String] {
        switch kind {
        case .distance: return ["imperial": "miles", "metric":"kms"]
        case .steps: return ["imperial": "steps", "metric":"steps"]
        }
    }
}

extension AMeasurement {
    func printValues() {
        print("\(imperial) \(units["imperial"]!) = \(metric) \(units["metric"]!)")
    }
}

let distance = AMeasurement(imperial: 30, metric: 48.28, kind: .distance)
let steps = AMeasurement(imperial: 30, metric: 30, kind: .steps)
let types = [distance, steps]

for type in types {
    type.printValues()
}

30,0 mil = 48,28 km
30,0 kroków = 30,0 kroków

1
Leo Dabus 20 listopad 2020, 23:56