【问题标题】:Swift protocol using another protocol causes errorSwift 协议使用另一个协议会导致错误
【发布时间】:2018-07-04 21:01:45
【问题描述】:

我正在使用 Swift 4。

我想定义一个问题。

问题由问题和答案组成。

问题可能是以下任何一种:String、Int、[Int]、Image、[Image] 或一些未定义的新类型,或者可能是上述的某种组合。

答案也可能是上述任何一种,但给定的问题可以有不同类型的答案。

(例如问题=(图片,“这是什么类型的动物?),答案=(“一只猫”))

所以我认为协议是可行的方法:

protocol Posable {
  var pose: String { get }
}

protocol Answerable: Hashable {
  var answer: String { get }
}

protocol Puzzle {
  var problem: Posable { get }
  var solution: Answerable { get }
}

我制作 Answerable Hashable 是因为我希望能够比较答案并创建答案集。

但我得到了解决方案:可回答的行:

'Protocol 'Answerable' 只能用作通用约束,因为它具有 Self 或关联的类型要求。

我明白为什么会这样,但是......

任何人都可以就如何实现这一点提出任何建议,以免我遇到这个问题吗?

如果可能的话,我热衷于使用协议来实现,部分原因是为了了解它们。

【问题讨论】:

标签: swift protocols


【解决方案1】:

我会用泛型解决它:

import UIKit

struct Posable<T> {
    var pose: T
}

struct Answerable<T> {
    var answer: T
}

extension Answerable: Equatable where T: Equatable {
    static func ==(lhs: Answerable<T>, rhs: Answerable<T>) -> Bool {
        return lhs.answer == rhs.answer
    }
}

extension Answerable: Hashable where T: Hashable {
    var hashValue: Int {
        return answer.hashValue
    }
}

struct Puzzle<T, U> {
    var problem: Posable<T>
    var solution: Answerable<U>
}

let image = UIImage() // Image of a cat
let pose = Posable<(UIImage, String)>(pose: (image, "What type of animal is this?"))
let solution = Answerable<String>(answer: "A cat")

let myPuzzle = Puzzle<(UIImage, String), String>(problem: pose, solution: solution)

泛型让您可以编写非常可重用的代码!在这里,您可以将任何课程用作问题或答案。

使用 Swift 类型继承:您还可以简化初始化:

let image = UIImage() // Image of a cat
let pose = Posable(pose: (image, "What type of animal is this?"))
let solution = Answerable(answer: "A cat")

let myPuzzle = Puzzle(problem: pose, solution: solution)

【讨论】:

  • 嗨,Dean,您的回复非常棒。它正是我想要的。我一直想知道泛型是否会有所帮助,但并没有太多使用它们。非常感谢。我会探索。非常感谢。
  • 而 Swift 4.1 的存在综合了 Equatable 和 Hasble 的一致性,所以我们可以说:扩展 Answerable: Equatable where T: Equatable { } 和 extension Answerable: Hashable where T: Hashable { }
【解决方案2】:

我不确定,但您可以从 Answerable 中删除 Hashable

protocol Posable {
    var pose: String { get }
}

protocol Answerable {
    var answer: String { get }
}

protocol Puzzle {
    var problem: Posable? { get }
    func getSolution<T: Hashable & Answerable>() -> T
}

【讨论】:

  • 感谢您的想法 - 有趣 - 我会考虑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-12
  • 1970-01-01
相关资源
最近更新 更多