Ho un protocollo, Address
, che eredita da un altro protocollo, Validator
, e Address
soddisfa il requisito Validator
nell'estensione.Impossibile utilizzare il protocollo come associatedtype in un altro protocollo a Swift
V'è un altro protocollo, FromRepresentable
, che ha un (ValueWrapper
) requisito associatedType
che dovrebbe essere Validator
.
Ora se provo a utilizzare Address
come associatedType
, quindi non viene compilato. Si dice,
dedotto tipo 'indirizzo' (facendo corrispondere requisito 'valueForDetail') è valida: non è conforme a 'Validator'.
L'utilizzo è illegale? Non dovremmo essere in grado di utilizzare Address
al posto di Validator
, poiché tutti gli Addresses
sono Validator
.
Di seguito è il pezzo di codice che sto cercando.
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
}
}
}
Aggiornamento: ha presentato una bug.
Va bene, ho capito, ma c'è qualche ragione per cui dobbiamo usare concreteType per un Tipo associato con un vincolo di protocollo? Il compilatore non genera alcun errore se usiamo Address come argomento per una funzione che si aspetta il validatore. –
Non capisco perché dobbiamo usare il tipo concreto se associatoTipo ha un vincolo di protocollo. Ha qualcosa a che fare con il comportamento di invarianza o l'allocazione di memoria? Avete qualche riferimento dove posso avere maggiori informazioni al riguardo. –
@VishalSingh Ho paura di non poter offrire una ragione migliore di "perché è così com'è" - non posso certamente pensare a una ragione per cui non dovrebbe essere possibile, visto che la versione non vincolata funziona bene . Anche io non riesco a trovare nulla sulla mailing list o sul bug tracker di questa evoluzione. Potrebbe valere la pena archiviare un [bug report] (https://bugs.swift.org/secure/Dashboard.jspa) e vedere cosa dicono di questo. – Hamish