简体   繁体   中英

Swift protocol extension `var { get }` override implementation's `let`

Implementing property with var and let behaves differently when the implementing struct is assigned to a variable typed as protocol .

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.

Is this designed behaviour of Swift?

I think this is a compiler bug. If you make a LetReq an optional string, it works as expected:

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

File a bug with Apple.

I think that behavior is correct.

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

path is String type not String?

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

req is type of Req . So req.path means type is String? and name is path

Req 's extension has default variable for path variable. so req.path refer that variable not LetReq 's path

It's vague... But I would bet on a bug.

At least for current implementation( swiftc 2.2);

  1. Swift supports method overloading by only different return types.
  2. But only for methods, not properties.
  3. So, all properties must have different names.

This can be proven by this.

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

But anyway, the compiler doesn't seem to check this redeclaration by protocol extension. So, LetReq instance actually provides two properties.

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

You can check this with this.

print(LetReq().path as String?)    // prints `Optional("Req")`.
print(LetReq().path as String)     // prints `LetReq`.

I believe this kind of property overloading must be prevented by compiler. For same reason of why they prevented property overloading in struct AA . So, that's a bug in my opinion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM