【问题标题】:Swift Generics: Conforming to protocol by constraining generic parameters to variable types defined by said protocolSwift 泛型:通过将泛型参数约束到由所述协议定义的变量类型来符合协议
【发布时间】:2022-02-19 19:53:43
【问题描述】:

在我的域模块中,我定义了一个协议分配、时间日志和分配时间日志。

在定义具体实现时,我想使用泛型来符合 AssignmentTimeLog 协议。为此,我将我的通用 A、T 参数限制为 Domain.Assignment 和 Domain.TimeLog 类型。为什么这不满足协议要求?我想了解发生了什么的逻辑。

// Domain Module
public protocol AssignmentTimeLog {

    var assignment: Assignment { get }
    var timeLog: TimeLog { get }
}

// My attempt to create an implementation trows an error
// Error: 
// Type 'AssignmentTimeLog<A, T>' does not conform to protocol 'AssignmentTimeLog'

import Domain

struct AssignmentTimeLog<A, T>: 
    Domain.AssignmentTimeLog where A: Domain.Assignment, T: Domain.TimeLog {
    
    var assignment: A
    var timeLog: T
 
}

对于上下文:使用泛型的原因是稍后我想在 AssignmentTimeLog 上定义一个扩展,其中 A & T 还实现另一个协议。这提供了额外的功能而无需额外的代码。具体类型实现域协议以及那些附加协议。

我试图通过阅读文档和多个博客来弄清楚这一点。但我似乎无法准确解决我所拥有的理解问题/差距。

【问题讨论】:

  • 你需要AssignmentTimeLog 协议做什么?只要有一个 AssignmentTimeLog&lt;A, T&gt; 结构就足够了,不是吗?
  • 这与我使用的架构有关。 MVVM,其中虚拟机和视图只能访问域模块中定义的协议。具体实现在一个单独的模块中。

标签: swift generics protocols


【解决方案1】:

协议所说的与您的实现所说的不同。

事实 1

根据协议这个getter

var assignment: Assignment { get }

可以返回任何符合Assignment的值。

事实 2

另一方面,你的实现在这里

var assignment: A

表示assignment 将包含特定类型的值A(恰好符合Assignment)。

这是两种截然不同的说法。

修复

这是一个简单的解决方法

protocol AssignmentTimeLog {
    
    associatedtype A: Assignment
    associatedtype B: TimeLog
    
    var assignment: A { get }
    var timeLog: B { get }
}


struct MyAssignmentTimeLog<A, T>: AssignmentTimeLog where A: Assignment, T: TimeLog {
    
    var assignment: A
    var timeLog: T
 
}

【讨论】:

  • 我想我看不到 2 个语句之间的区别。你是说A恰好符合Assignment。但是,我将 A 和 T 限制为特定类型的事实是否意味着该结构的任何实例都必须具有所述类型的这些属性? ......“A”可以是任何符合这种类型的东西......关于修复我实际上尝试过它确实有效,除了我不能使用协议作为类型(直到下一个版本的 Swift 出来)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多