2016-05-26 12 views
1

Die Implementierung der Eigenschaft mit var und let verhält sich anders, wenn die implementierende Struktur einer Variablen zugewiesen ist, die als typisiert ist.Swift-Protokollerweiterung `var {get}` override Implementierung `let`

protocol Req { 
    var path: String? { get } 
} 
extension Req { 
    var path: String? { return "Req" } 
} 

struct LetReq: Req { 
    let path = "LetReq" 
} 
struct VarReq: Req { 
    var path: String? { return "VarReq" } 
} 

var req: Req! 

req = VarReq() 
req.path // prints "VarReq" 

req = LetReq() 
req.path // prints "Req" not "LetReq" which seems very awkward. 

Ist dieses Verhalten von Swift ausgelegt?

Antwort

1

Ich denke, das ist ein Compiler Bug. Wenn Sie eine LetReq eine optionale Zeichenkette machen, funktioniert es wie erwartet:

struct LetReq: Req { 
    let path: String? = "LetReq" 
} 

File a bug mit Apple.

+1

Oder http://bugs.swift.org – jtbandes

0

Ich denke, dass das Verhalten richtig ist.

struct LetReq: Req { 
    let path = "LetReq" 
} 

Pfad String Typ nicht String?

var req: Req! 
req = LetReq() 
req.path 

req Typ Req ist. So bedeutet req.path Typ ist String? und Name ist path

Req ‚s Erweiterung Standardvariable für path Variable hat. also req.path beziehen diese Variable nicht LetReq 's path

0

Es ist vage ... Aber ich würde auf einen Fehler wetten.

Zumindest für die aktuelle Implementierung (swiftc 2.2);

  1. Swift unterstützt das Überladen von Methoden nur durch unterschiedliche Rückgabetypen.
  2. Aber nur für Methoden, nicht Eigenschaften.
  3. Also müssen alle Eigenschaften unterschiedliche Namen haben.

Dies kann dadurch nachgewiesen werden.

struct AA { 
    func a() -> String { return "" } 
    func a() -> String? { return "" } 
    var b: String { return "" } 
    var b: String? { return "" } // Error: Invalid redeclaraion of `b`. 
} 

Aber wie auch immer, der Compiler scheint nicht dieses Neudeklaration durch Protokoll-Erweiterung zu überprüfen. Also, LetReq Instanz bietet tatsächlich zwei Eigenschaften.

var path: String { get } 
var path: String? { get } 

Sie können dies überprüfen.

Ich glaube, dass diese Art der Eigenschaft Überladung vom Compiler verhindert werden muss. Aus dem gleichen Grund, warum sie eine Überlastung der Eigenschaften in struct AA verhindert. Also, das ist ein Fehler meiner Meinung nach.