Mam protokół, Address
, która dziedziczy z innego protokołu, Validator
i Address
spełnia wymóg w rozszerzeniu Validator
.Nie można używać protokołu jako associatedtype w innym protokole w Swift
Istnieje inny protokół, FromRepresentable
, który ma wymaganie associatedType
(ValueWrapper
), które powinno być Validator
.
Teraz, jeśli spróbuję użyć Address
jako associatedType
, to się nie skompiluje. Mówi,
Wnioskowany typ „Address” (dopasowując wymóg „valueForDetail”) jest nieprawidłowy: nie spełnia „Weryfikator”.
Czy korzystanie z tego urządzenia jest nielegalne? Nie powinniśmy móc używać Address
w miejsce Validator
, ponieważ wszystkie Addresses
są.
Poniżej znajduje się fragment kodu, który próbuję.
enum ValidationResult {
case Success
case Failure(String)
}
protocol Validator {
func validate() -> ValidationResult
}
//Address inherits Validator
protocol Address: Validator {
var addressLine1: String {get set}
var city: String {get set}
var country: String {get set}
}
////Fulfill Validator protocol requirements in extension
extension Address {
func validate() -> ValidationResult {
if addressLine1.isEmpty {
return .Failure("Address can not be empty")
}
return .Success
}
}
protocol FormRepresentable {
associatedtype ValueWrapper: Validator
func valueForDetail(valueWrapper: ValueWrapper) -> String
}
// Shipping Address conforming to Address protocol.
// It should also implicitly conform to Validator since
// Address inherits from Validator?
struct ShippingAddress: Address {
var addressLine1 = "CA"
var city = "HYD"
var country = "India"
}
// While compiling, it says:
// Inferred type 'Address' (by matching requirement 'valueForDetail') is invalid: does not conform
// to 'Validator'.
// But Address confroms to Validator.
enum AddressFrom: Int, FormRepresentable {
case Address1
case City
case Country
func valueForDetail(valueWrapper: Address) -> String {
switch self {
case .Address1:
return valueWrapper.addressLine1
case .City:
return valueWrapper.city
case .Country:
return valueWrapper.country
}
}
}
Aktualizacja: złożyła bug.
Dobra, rozumiem, ale czy jest jakiś powód, dla którego musimy użyć concreteType dla relatedType z ograniczeniem protokołu? Kompilator nie wydaje żadnego błędu, jeśli użyjemy adresu jako argumentu dla funkcji, która oczekuje walidatora. –
Nie rozumiem tego, dlaczego musimy użyć konkretnego typu, jeśli relatedType ma ograniczenie protokołu. Czy ma to coś wspólnego z zachowaniem niezmienniczym lub alokacją pamięci? Czy masz jakieś odniesienia, gdzie mogę więcej informacji na ten temat. –
@VishalSingh Obawiam się, że nie mogę zaoferować lepszego powodu niż "ponieważ tak właśnie jest" - na pewno nie mogę wymyślić powodu, dla którego nie byłoby to możliwe, ponieważ ta nieskrępowana wersja działa dobrze . Nie mogę też znaleźć niczego na liście mailingowej szybkiego śledzenia ewolucji ani na temat tego narzędzia do śledzenia błędów. Warto również zgłosić [zgłoszenie błędu] (https://bugs.swift.org/secure/Dashboard.jspa) i zobaczyć, co o nim mówią. – Hamish