我可以直接从协议扩展类型访问默认静态变量吗?
Can I directly access a default static var from the type of a protocol extension?
为了 Swift 的乐趣,我想我应该为 GCD
构建一些替代的具体化 API。所以我把它扔在了操场上:
import Foundation
typealias DispatchQueue = dispatch_queue_t
extension DispatchQueue {
static var main:DispatchQueue {
return dispatch_get_main_queue()
}
}
let main = DispatchQueue.main
但这会在最后一行产生错误:
Static member 'main' cannot be used on instance of type 'DispatchQueue.Protocol' (aka 'OS_dispatch_queue.Protocol')
我不确定这是在告诉我什么。我的意思是,我读过它。但我没有看到真正的问题。我查看了 Double
如何为 NaN
之类的内容提供类型变量,但我不确定为什么我不能使用类似的访问器扩展另一种类型。
(我确实尝试过没有 typealias
的替代方法,没有区别)
更新:@Kametrixom 的回答没有立即帮助,但它可能最终做出了贡献。这是我必须做的才能让灯泡亮起来。
class Foo {
static var Bar:Int {
return 42
}
}
Foo.Bar --> 42
好的,成功了,现在是一个结构。
struct Yik {
static var Yak:Int {
return 13
}
}
Yik.Yak --> 13
这也奏效了。现在是一个具有扩展默认实现的协议:
protocol Humble { }
extension Humble {
static var Pie:Int {
return 23
}
}
Humble.Pie --> DOES NOT WORK
但是,使用协议扩展 class 或结构:
extension Foo: Humble { }
Foo.Pie --> 23
这行得通。我犯的错误(我认为?)是假设有第一个 class 谦虚类型 运行 实例,并附有该行为,我可以调用它,ala composition style。相反,它只是要添加到 struct/class 类型的行为模板。
我已经更改了问题的标题。答案是否定的
如果你去看dispatch_queue_t
的定义,你会发现它是一个协议:
public typealias dispatch_queue_t = OS_dispatch_queue
public protocol OS_dispatch_queue : OS_dispatch_object {}
这意味着您实际上并不是在扩展协议本身,而是在扩展符合它的类型。这意味着要让它工作,您需要获取某处协议的实例,获取它的动态类型,然后您可以调用 main
:
let DispatchQueueT = (dispatch_queue_create("", DISPATCH_QUEUE_SERIAL) as dispatch_queue_t).dynamicType
DispatchQueueT.main
为了 Swift 的乐趣,我想我应该为 GCD
构建一些替代的具体化 API。所以我把它扔在了操场上:
import Foundation
typealias DispatchQueue = dispatch_queue_t
extension DispatchQueue {
static var main:DispatchQueue {
return dispatch_get_main_queue()
}
}
let main = DispatchQueue.main
但这会在最后一行产生错误:
Static member 'main' cannot be used on instance of type 'DispatchQueue.Protocol' (aka 'OS_dispatch_queue.Protocol')
我不确定这是在告诉我什么。我的意思是,我读过它。但我没有看到真正的问题。我查看了 Double
如何为 NaN
之类的内容提供类型变量,但我不确定为什么我不能使用类似的访问器扩展另一种类型。
(我确实尝试过没有 typealias
的替代方法,没有区别)
更新:@Kametrixom 的回答没有立即帮助,但它可能最终做出了贡献。这是我必须做的才能让灯泡亮起来。
class Foo {
static var Bar:Int {
return 42
}
}
Foo.Bar --> 42
好的,成功了,现在是一个结构。
struct Yik {
static var Yak:Int {
return 13
}
}
Yik.Yak --> 13
这也奏效了。现在是一个具有扩展默认实现的协议:
protocol Humble { }
extension Humble {
static var Pie:Int {
return 23
}
}
Humble.Pie --> DOES NOT WORK
但是,使用协议扩展 class 或结构:
extension Foo: Humble { }
Foo.Pie --> 23
这行得通。我犯的错误(我认为?)是假设有第一个 class 谦虚类型 运行 实例,并附有该行为,我可以调用它,ala composition style。相反,它只是要添加到 struct/class 类型的行为模板。
我已经更改了问题的标题。答案是否定的
如果你去看dispatch_queue_t
的定义,你会发现它是一个协议:
public typealias dispatch_queue_t = OS_dispatch_queue
public protocol OS_dispatch_queue : OS_dispatch_object {}
这意味着您实际上并不是在扩展协议本身,而是在扩展符合它的类型。这意味着要让它工作,您需要获取某处协议的实例,获取它的动态类型,然后您可以调用 main
:
let DispatchQueueT = (dispatch_queue_create("", DISPATCH_QUEUE_SERIAL) as dispatch_queue_t).dynamicType
DispatchQueueT.main