英文:
Swift: Access to static var of a protocol implementation
问题
I get a compiler error when I try to access a property of my protocol implementation and would like to understand why this is not working:
"Static member 'foo' cannot be used on an instance of type 'any MyProtocol'"
protocol MyProtocol {
static var foo: Int { get }
}
struct ProtocolImplementation: MyProtocol {
static let foo: Int = 2
}
struct HoldsAProtocolImplementation {
var bar: MyProtocol
}
let a = HoldsAProtocolImplementation(bar: ProtocolImplementation())
print(a.bar.foo) // error: Static member 'foo' cannot be used on an instance of type 'any MyProtocol
I tried to understand the error message. Any instance that conforms to "MyProtocol" should have a (static) var foo. So why am I not allowed to access it?
英文:
I get a compiler error when I try to access a property of my protocol implementation and would like to understand why this is not working:
Static member 'foo' cannot be used on instance of type 'any MyProtocol'
protocol MyProtocol {
static var foo: Int { get }
}
struct ProtocolImplementation: MyProtocol {
static let foo: Int = 2
}
struct HoldsAProtocolImplementation {
var bar: MyProtocol
}
let a = HoldsAProtocolImplementation(bar: ProtocolImplementation())
print(a.bar.foo) // error: Static member 'foo' cannot be used on instance of type 'any MyProtocol
I tried to understand the error message. Any instance that conforms to "MyProtocol" should have a (static) var foo. So why am I not allowed to access it?
答案1
得分: 1
以下是您要翻译的内容:
有两个基本问题。
第一个问题是a.bar
是一个实例,根据定义,您不能在实例上使用static
成员。您必须指定类型。要调用foo
,您需要编写类似以下的内容
print(ProtocolImplementation.foo)
// ^^^^^^^^^^^^^^^^^^^^^^ 这是一个具体类型
这导致了第二个问题,如果编译器只知道一个实例符合某个协议,那么它无法决定要使用哪个符合类型上的静态属性。因此,您不能编写
print(MyProtocol.foo)
因为编译器需要一个具体的类型来获取静态属性。
有办法解决这个问题。一个方法是扩展协议,添加一个仅获取静态属性的实例属性
protocol MyProtocol
{
static var foo: Int { get }
}
extension MyProtocol
{
var foo: Int { Self.foo }
}
print(a.bar.foo) // 打印 2
另一种方法是在运行时获取类型
print(type(of: a.bar).foo)
可能还有其他更巧妙的方法来实现您想要的功能。
英文:
There are two basic issues.
The first is that a.bar
is an instance and by definition you cannot use a static
member on an instance. You have to specify the type. To invoke foo
you need to write something like
print(ProtocolImplementation.foo)
// ^^^^^^^^^^^^^^^^^^^^^^ this is a concrete type
This leads to the second problem, if all the compiler knows about an instance is that it conforms to a certain protocol, then it can't decide which static property on which conforming type to use. So you can't write
print(MyProtocol.foo)
because the compiler needs a concrete type from which to get the static property.
There are ways around this. One would be to extend the protocol with an instance property that just gets the static property
protocol MyProtocol
{
static var foo: Int { get }
}
extension MyProtocol
{
var foo: Int { Self.foo }
}
print(a.bar.foo) // prints 2
Another would be to get the type at runtime
print(type(of: a.bar).foo)
There are probably other more clever methods of doing what you want.
答案2
得分: 0
A static property belongs to the type itself, not to an instance.
Therefore you have to call it on the type
print(ProtocolImplementation.foo)
英文:
A static property belongs to the type itself, not to an instance.
Therefore you have to call it on the type
print(ProtocolImplementation.foo)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论