首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >要求关联类型在@convention(c)块中可表示

要求关联类型在@convention(c)块中可表示
EN

Stack Overflow用户
提问于 2017-05-11 15:50:45
回答 1查看 253关注 0票数 6

我想有一种通用的方法来做像Swift 3这样的事情:

代码语言:javascript
复制
public protocol Callable {
    associatedtype In : CVarArg
    associatedtype Out : CVarArg
}

public struct IntCallable : Callable {
    public typealias In = Int
    public typealias Out = Double

    public typealias FunctionalBlock = @convention(c) (In) -> Out

    public func call(_ block: FunctionalBlock) { /* do stuff */ }
}

所以我希望它看起来更像这样:

代码语言:javascript
复制
public protocol Callable {
    associatedtype In : CVarArg
    associatedtype Out : CVarArg
    typealias FunctionalBlock = @convention(c) (In) -> Out
}

public struct IntCallable : Callable {
    public typealias In = Int
    public typealias Out = Double
}

public extension Callable {
    public func call(_ block: FunctionalBlock) { /* do stuff */ }
}

但是,我得到了错误:

代码语言:javascript
复制
'(Self.In) -> Self.Out' is not representable in Objective-C, so it cannot be used with '@convention(c)'

我是否可以对输入/输出关联类型设置任何约束,允许我声明FunctionalBlock的泛型形式?没有@convention(c),它工作得很好,但是我需要它来形成一个C函数调用。

EN

回答 1

Stack Overflow用户

发布于 2022-03-01 05:34:27

这在Swift中目前是不可能的,因为Swift如何管理作为协议传递的值,而CVarArg是一种协议。

幕后发生的事情是,当在协议的保护伞下传递一个值时,Swift编译器创建一个存在容器来包装该值,这个值在被调用的站点上透明地被打开。

基本上你的街区看起来是这样的:

代码语言:javascript
复制
typealias FunctionalBlock = @convention(c) (Container<In>) -> Container<Out>

由于这种幕后转换,您没有传递可以用C表示的值,因此会出现错误。

这与其他与协议相关的问题非常相似,比如著名的Protocol doesn't conform to itself?

您最好的选择是为所有符合CVarArg的类型添加重载,因为这是一个有限且不可更改的列表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43920260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档