2015-05-06 9 views
8

Recentemente ho letto Protocols, Generic Type Constraints and Arrays in Swift. La mia domanda riguarda i seguenti due esempi dal blog:Comportamento dei protocolli con Self

Il codice:

protocol MyProtocol1 { 
    var myValue: Self { get } 
} 

let array: [MyProtocol1] = [] // Error. 

genera l'errore:

Protocol 'MyProtocol1' can only be used as a generic constraint because it has Self or associated type requirements.

che è previsto e ci sono stati diversi SO domande riguardanti l'argomento. Tuttavia, modificando myValue in una funzione non c'è più alcun errore, tuttavia in entrambi i casi viene restituito Self.

protocol MyProtocol2 { 
    func myValue() -> Self 
} 

let array: [MyProtocol2] = [] // This is okay. 

Qualcuno conosce la causa di questo comportamento apparentemente strano?

+0

Si consiglia di discuterlo sui devforum. Sospetto che si tratti di un caso isolato e potrebbe non essere intenzionale. Gli sviluppatori di Swift hanno molte più probabilità di fornire una risposta definitiva. –

+0

Hai trovato una risposta a questo comportamento? – bartzy

risposta

0

Non ho una risposta definitiva a questo, ma ritengo che ciò potrebbe essere dovuto alla dimensione della classe e al layout interno.

Avere un tipo associato o un membro di tipo Self influirà sulle dimensioni dell'oggetto e quindi sulla dimensione dell'array, ma l'uso del metodo Self come metodo restituirà la dimensione dell'oggetto.

+0

Questa è un'idea interessante, ma se fosse vera, ci si aspetterebbe che il "Sé" della boxe lo risolvesse. Ad esempio, se hai dichiarato 'var myValue: Self? {get} '. Questo metterebbe il "Sé" di dimensioni sconosciute all'interno di un "Optional" di dimensioni note e risolverebbe il problema del layout. (Questa tecnica è usata per enumerazioni ricorsive, ad esempio, che hanno questo problema di dimensioni.) Ma non aiuta. –

2

E 'spiegato a circa 18 minuti in questo video: https://developer.apple.com/videos/wwdc/2015/?id=408

Perché i vostri riferimenti di protocollo "io" può essere utilizzato solo come un vincolo generico non come un tipo.

Esempio: Diciamo che 2 strutture implementano il protocollo - Duke & Argento.

Se è stata creata una matrice di protocollo2 ([protocollo2]), la matrice potrebbe contenere entrambi i Duchi sono argenti.

myValue specifica espressamente che il valore restituito deve essere auto. Ciò significa che un Duca deve restituire un Duca e un Argento deve restituire un Argento. Pertanto, non è possibile avere Dukes & Silvers nello stesso array perché le loro funzioni MyValue hanno valori di ritorno diversi.

Per risolvere il problema, è possibile:

1) Effettuare il tipo di ritorno di myValue Protocollo2 in modo che Duchi e Silvers sia solo restituiscono un tipo Protocollo2

2) Fai una serie di farmaci generici che sono conformi al protocollo2

+0

Hai perso il punto della domanda. Un protocollo con una proprietà di tipo 'Self' -' var myValue: Self {get set} '- avrà' Requisiti di tipo Self o associati 'e potrà essere usato come vincolo di tipo. Al contrario, un protocollo con una funzione che restituisce un valore di tipo 'Self' -' func myValue() -> Self' - può essere usato come tipo e non solo come tipo.La questione sconcertante è perché un requisito * di proprietà * del protocollo di tipo 'Self' ha un comportamento diverso rispetto a un requisito * function * del protocollo che restituisce un valore di tipo' Self'. –

+0

Ah, davvero. Non ho letto la domanda a fondo. Grazie. – JoeyBartez

Problemi correlati