-1

So I'm constructing a Foo object and this concrete Foo object has a bar2 which is a Bar. That bar complies with the BarProt protocol, but still it's not recognized. What can I do about this? I need the var2 to be compliant with Bar in this case.

For the reason why: I have many kinds of Bar that slightly differ and I tried to find the lowest common denominator which I extracted into BarProt, so I could reuse the logic for handling Bar-like objects .

(I'm basically making various lookups based on the properties of the bar objects, and want to make a general resolver for a BarProt and then handle the specifics elsewhere).

protocol BarProt {
  var bar: String {get}
}
struct Bar: BarProt {
  var bar: String
}

protocol FooProt {
  var var1: String {get}
  var var2: BarProt {get}
}

struct Foo: FooProt {
  let var1: String
  let var2: Bar // I'm required to change it to BarType, but I really don't want to, since Bar contains so much more that BarType
}

let barInstance = Bar(bar: "Hello")
print(Foo(var1: "String", var2: barInstance))

And the error:

protocol requires property 'var2' with type 'BarProt'; do you want to add a stub?
  var var2: BarProt

Novellizator
  • 13,633
  • 9
  • 43
  • 65
  • That's expected. `FooProt` requires `var2` to be of any type that implements `BarProt`, but in your case it's a concrete type, so you can't assign to it a value of some other type implementing `BarProt` - hence, `Foo` doesn't implement `FooProt`. Why do you need `var2` to be of `Bar` type? – mag_zbc Jun 11 '19 at 14:57
  • Assuming your protocol requirement is `var var2: BarProt { get }`, then this is a duplicate of [Why can't a get-only property requirement in a protocol be satisfied by a property which conforms?](https://stackoverflow.com/q/42561685/2976878). – Hamish Jun 11 '19 at 14:59
  • Please show real code. The FooProt declaration does not compile (because you have no `{get}` or `{get set}` for `var2`. Show code which compiles up to the point where the error can be reproduced. – matt Jun 11 '19 at 15:04

2 Answers2

0

var2 has to be BarProt. Does this work for you?

protocol BarProt {
    var bar: String {get}
}
struct Bar: BarProt {
    var bar: String
}

protocol FooProt {
    var var1: String {get}
    var var2: BarProt { get }
}

struct Foo: FooProt {
    var var2: BarProt    
    let var1: String

}

let barInstance = Bar(bar: "Hello")
print(Foo(var2: barInstance, var1: "String"))

DàChún
  • 4,751
  • 1
  • 36
  • 39
  • unfortunatelly not, because I need to have `var2: Bar` at all costs. I made a protocol to make a lowest common denominators between all the Bar-kinds so I could reuse as many functions as possible – Novellizator Jun 11 '19 at 14:59
0

Here,

struct Foo: FooProt {
  let var1: String
  let var2: Bar
}

var2 doesn't conform to the FooProt protocol, replace its type with BarProt.

Also, properties in protocols must have the explicit get or get set specifiers, so add a specifier to every property in your protocols.

Renzo Tissoni
  • 642
  • 9
  • 21