泛型类的 Swift 委托协议

2023-12-20

我有一堂课,StateMachine,这是通用的,允许将不同的状态集实现为例如枚举。我想用一个StateMachineDelegate当状态机进入新状态时通知委托的协议。

但这不起作用,因为委托协议对于类型要求也是通用的。该错误显示了哪里delegate财产已申报。

protocol StateType: Hashable {}

protocol StateMachineDelegate: class {
    typealias S: StateType
    func stateMachine(stateMachine: StateMachine<S>, didEnterState newState: S)
}

class StateMachine<S: StateType> {
    typealias State = S

    weak var delegate: StateMachineDelegate?
    //~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
    //Protocol 'StateMachineDelegate' can only be used as a generic constraint because it has Self or associated type requirements

    var currentState: State {...}

    init(initialState: State) {...}

    func applyState(toState: State) -> Bool {
        ...
        currentState = toState
        delegate?.stateMachine(self, didEnterState: toState)
        ...
    }
}



我需要以某种方式将其关联起来StateMachineDelegate.S == S in the StateMachine类,但我不确定如何做到这一点,或者是否可能。我试过:

class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> {
    ...
    weak var delegate: D?
    ...
}

但后来我陷入尝试修改协议以正确声明通用类型的困境StateMachine。在创建委托时必须预先声明委托的类型似乎并不正确StateMachine.


看看这个解决方法是否可以满足您的需求,它使用@autoclosure解决递归泛型定义的问题:

class StateMachine<S: Printable, D: StateMachineDelegate where S == D.StateType> {

    var currentState: S {
        didSet {
            // The observer
            if let delegate = self.delegate {
                delegate.stateMachine(self, didEnterState: self.currentState)
            }
        }
    }

    var delegate: D?

    init(initialState: S) {
        self.currentState = initialState
    }


}


protocol StateMachineDelegate: class {
    typealias StateType: Printable

    // Workaround with autoclosure
    func stateMachine(machine: @autoclosure() -> StateMachine<StateType, Self>, didEnterState newState: StateType)
}

final class ADelegate: StateMachineDelegate {
    typealias StateType = Int
    func stateMachine(machine: @autoclosure  () -> StateMachine<StateType, ADelegate>, didEnterState newState: StateType) {
        // Need to _unbox_ the sander from the closure
        let sender = machine()
        println(newState)
        println("State from sender: \(sender.currentState)")
    }
}

let stateMachine = StateMachine<Int, ADelegate>(initialState: 24)

stateMachine.delegate = ADelegate()
stateMachine.currentState = 50

顺便说一下,考虑一下,如果你得到了砂光机,可能你就不需要得到newState通过了。 我用了Printable代替Hashable例如。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

泛型类的 Swift 委托协议 的相关文章

随机推荐

  • 从firebase存储Xamarin获取图像下载url

    我试图从上传到 firebase 存储的照片中获取图像 url 以便我可以将图像的引用存储在另一个表中 这将使我能够在整个应用程序的其他位置显示图像 我目前有 private void UploadPhoto if filePAth nul
  • 如何使用 Python 从 Windows 7 中迭代连接的 iPhone 上的照片?

    当我将 iPhone 连接到 Windows 7 系统时 Windows 资源管理器会打开 DCIM 内容的虚拟文件夹 我可以通过 Pywin32 218 访问 shell 库接口 如下所述 我可以在 python 中使用库抽象吗 http
  • 需要配置的打字稿

    我正在构建一个 Web 应用程序 其中的开发不是基于 TypeScript 构建的 但是该应用程序具有我想要使用插件样式进行的集成点 这就是使用 TypeScript 的地方 TypeScript 代码位于第二个解决方案中 我将 js 文件
  • git status 报告新克隆的存储库中修改的文件

    Solved 远程存储库似乎包含两个名称相同的文件 除了第一个字母之外 这导致我的系统上的文件被覆盖 从而导致以下问题 Update 看起来它与换行符无关 但我还找不到解释 事情是这样的 git status报告FileStartingWi
  • 获取在 Windows 上构建轮错误 Pygame 的要求

    我正在尝试使用以下命令安装 Pygame pip install pygame我得到这个结果 pip 安装 pygame 收集pygame 使用缓存的 pygame 2 4 0 tar gz 13 2 MB 安装构建依赖项 完成 获取构建轮
  • 服务结构具有 100 万个键的可靠字典性能

    我正在使用包含约 100 万个键的可靠字典来评估 Service Fabric 的性能 我得到的结果相当令人失望 所以我想检查我的代码或我的期望是否错误 我有一本初始化的字典dict await stateManager GetOrAddA
  • jQuery.post 刷新我的页面?

    我的页面上有以下带有表单的代码 但是当我点击提交时 我的页面似乎刷新了 form
  • js如何将objectName打印到控制台

    使用 webdev 工具控制台时 如果输入浏览器对象 则会返回控制台 gt console Console gt console object Console gt console log console undefined gt Cons
  • rm 无法从脚本中通过通配符删除文件,但可以在 shell 提示符下工作

    我在 Linux shell 脚本中遇到了一个非常愚蠢的问题 我想删除目录中扩展名为 bz2 的所有文件 在我调用的脚本中 rm archivedir bz2 其中 archivedir 是目录路径 应该很简单 不是吗 不知何故 它因以下错
  • [iOS][AWS Cognito] 已弃用“登录”:使用“AWSIdentityProviderManager”

    我一直在尝试使用 Amazon Cognito 在 iOS 上使用 Facebook 和 Twitter 对用户进行身份验证 我无法实施 因为官方文件太旧了 这是我的代码 NSString token FBSDKAccessToken cu
  • 使用 Python 和 mySQL 进行动态 SQL 查询

    我有多个表 这些表在网格中的值更改后更新 这些表并不总是具有相同的键或列 因此我无法明确命名列或格式 唯一相同的是键所在的列 我知道我目前这样做的方式是不正确的 并且使我容易受到注入攻击 我还遇到了一个问题 其中某些值包含在 SQL 语句中
  • jQuery 滑块适用于 div 元素而不仅仅是图像

    我已经在我正在处理的页面底部为一些 建议项目 创建了 div 和容器 希望它成为一个滑块 您可以在其中左右单击以查看更多内容 但是我见过的所有 jQuery 滑块都只适用于图像 轮播 对于这种情况 人们可以向我推荐一些滑块 因为它不仅仅是图
  • MySQL 从多列中选择并计算值

    我正在尝试创建一个 mysql 选择查询 该查询根据其他两个字段计算一个值 这是我的查询 SELECT request id unit cost quantity AS claim value FROM xx non part usage
  • 如何判断 Clojure 中的 dosync 是否正在更新引用?

    我需要对参考进行一些更新 但我想选择在参考不大量使用时执行更新的时间 有没有一种方法可以以编程方式判断引用何时处于事务中 你可以add watch http clojure github com clojure clojure core a
  • SVG 与 HTML5 Canvas 中的图表

    我想开始一个项目 在该项目中 我需要绘制由用线条连接的圆角矩形组成的图表 以及单击某些元素时的 JavaScript 操作 这需要在所有现代浏览器中工作 SVG 和 HTML5 Canvas 似乎都可以做到这一点 所以我想知道什么是最好的
  • SimpleXml 存在命名空间问题

    我几乎尝试了所有方法 但我似乎无法从以下 SimpleXMLElement 转储中读取命名空间 m inline 元素以及 feed 和 title 子元素 SimpleXMLElement 235 attributes array 4 r
  • 在 python 中使用正则表达式进行搜索和替换

    str name John company AB C corp id 12g 123 12 12 B C替换为空字符串 g 1替换为空字符串 必填字符串 str name John company A corp id 1223 12 12
  • 在 Intellij 中使用 springloaded 重新加载类后断点不起作用

    我正在 Intellij 中使用 应用程序 配置运行我的 java 应用程序 我正在使用这些 vm 选项来使用 springloaded javaagent springloaded 1 2 0 RELEASE jar noverify 使
  • 将迁移作为 Django Web 应用程序的 MS Azure 应用程序服务发布管道的一部分运行

    我想知道是否有人有集成的经验python manage py migrate命令进入 MS Azure 发布管道 该应用程序正在通过 DevOps 使用 CI CD 管道进行部署 在发布管道部分 应用程序被部署到三个不同的阶段 开发 测试和
  • 泛型类的 Swift 委托协议

    我有一堂课 StateMachine 这是通用的 允许将不同的状态集实现为例如枚举 我想用一个StateMachineDelegate当状态机进入新状态时通知委托的协议 但这不起作用 因为委托协议对于类型要求也是通用的 该错误显示了哪里de