Is there a good linguistic reason why access modifiers which restrict access
should not be allowed in protocols? I mean something like this
public protocol Foo
{
mutating func foo( Int )->Void
internal var bar : Array<Int> { get set } // <-
can’t do this
}
What do I think this would mean? I mean by it that a Type conforming to Foo
must be public, and must have a public function foo and an internal variable
bar.
Why would I want to do this? What I was trying to do is use protocol extensions
to provide a default implementation of a protocol method, one which requires a
backing property. So the code I really wanted to write was this
public protocol Foo
{
mutating func foo( Int ) -> Void
}
That’s my public definition of the Foo protocol, I don’t care how it’s
implemented. Let’s say however that a very usual implementation of foo() would
use an Array<Int> property like this
public struct FooImpl : Foo
{
internal var bar = Array<Int>()
public mutating func foo( i : Int ) -> Void { bar.append( i ) }
}
But I have lots of Types which want to implement Foo and although I don’t want
to have to copy the method body of foo() everywhere, it might be a little
longer in real life. or perhaps Foo has 10 different methods
I could use my FooImpl in all those Types by composition, but then for each
method in Foo I have to explicitly call the implementer version. If there’s
many methods, that’s repeated code in every Type.
public struct AnotherFooImpl : Foo
{
internal var fooImplementer = FooImpl()
public mutating func foo( i : Int ) -> Void {
fooImplementer.foo( i ) ) // do this for each method in Foo
}
What I’d like is for the compiler to do this for me with a protocol extension,
I can do this like so by extending Foo like this and using an extension
public protocol FooImplementedWithArray : Foo
{
var bar : Array<Int> { get set }
}
extension FooImplementedWithArray
{
public mutating func foo( i : Int ) -> Void { bar.append( i ) }
}
and then the implementation just requires defining the stored property
public struct AThirdFooImpl : FooImplementedWithArray
{
public var bar = Array<Int>() // that’s all we need =
the protocol extension supplies the rest
}
But the problem is .. bar is now public. Worse, as the foo() was cunningly
declared to be mutating, bar has to be a { get set } property, anyone using the
class can totally break it.
If I make FooImplementedWithArray internal, bar is internal, however that also
makes foo() internal and means none of my implementations can be anything more
than internal. My feeling was that if you were allowed to mark things in a
protocol as more restricted than the protocol itself, eg make bar private
within a public FooImplementedWithArray, that would work and the compiler could
synthesise the code you would write yourself.
Is there a reason why all protocol elements must have the same visibility as
the protocol itself otherwise there’s a potential visibility inconsistency, or
is this just a feature I should request.
Is there another way to do what I’m trying to do here, have the compiler do my
work for me but have my stored property hidden?
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]