ios - 多层次深度泛型/协议(protocol)的 Swift 泛型和协议(protocol)问题

标签 ios swift generics swift3

我正计划为芝加哥的 children 制作一个闪存卡应用程序,只要他们符合相同的协议(protocol),它就可以接受多种问题。理想情况下,将有许多不同的游戏,难度各不相同,并且 View 将能够使用所有游戏,因为所有游戏都将遵循相同的协议(protocol)。我希望每个回合都能够采用完全不同类型的结构,只要它是可等式的。

我觉得我快接近了,但我一辈子都想不出如何让游戏在不出错的情况下接收任何数据……我觉得我快接近了,但我做不到不要越过这个减速带。

我不断收到诸如“TurnDefinable 只能用作通用约束,因为它具有 Self 或关联类型要求”之类的错误

protocol GameDefinable {
    associatedtype TurnType: TurnDefinable
    var turns: [TurnType] { get }
}

class Game<T: TurnDefinable>: GameDefinable {
    var turns: [T]

    init(turns: [T]) {
        self.turns = turns
    }
}

class Turn<A: AnswerDefinable>: TurnDefinable {
    var question: String
    var correctAnswer: A
    var answers: [A]

    init(question: String, answers: [A], correctAnswer: A) {
        self.question = question
        self.answers = answers
        self.correctAnswer = correctAnswer
    }
}

protocol TurnDefinable {
    associatedtype AnswerType
    /// Localized string to ask the user a question they must answer
    var question: String { get }
    /// Array of possible answers
    var answers: [AnswerType] { get }
    /// Correct answer per turn
    var correctAnswer: AnswerType { get }
}

protocol AnswerDefinable: Equatable {
    // Will have more stuff here like localized formatted string, etc
}

// Just created this test pretending our answers will be Ints
struct ExampleOfAnAnswerStruct: AnswerDefinable {
    static func == (lhs: ExampleOfAnAnswerStruct, rhs: ExampleOfAnAnswerStruct) -> Bool {
        return lhs.testInteger == rhs.testInteger
    }

    // Just created this to get the equatable
    var testInteger = 0
}


struct ExampleOfAnAnswerStruct2: AnswerDefinable {
    var string: String
    static func == (lhs: ExampleOfAnAnswerStruct2, rhs: ExampleOfAnAnswerStruct2) -> Bool {
        return lhs.string == rhs.string
    }
}

任何帮助将不胜感激...

编辑:我现在更接近了,我只需要弄清楚如何能够使用不同答案类型的两个回合

let turnExample1 = Turn<ExampleOfAnAnswerStruct>(question: "Which is the lonliest number?", answers: [ExampleOfAnAnswerStruct(testInteger: 1), ExampleOfAnAnswerStruct(testInteger: 2), ExampleOfAnAnswerStruct(testInteger: 3)], correctAnswer: ExampleOfAnAnswerStruct(testInteger: 1))
let turnExample2 = Turn<ExampleOfAnAnswerStruct2>(question: "You say goodbye, and i say ...", answers: [ExampleOfAnAnswerStruct2(string: "hello"), ExampleOfAnAnswerStruct2(string: "goodbye")], correctAnswer: ExampleOfAnAnswerStruct2(string: "hello"))

let testGame = Game(turns: [turnExample1, turnExample2])

我很接近!感谢迄今为止的所有帮助!

最佳答案

我有一个想法,但我不确定。

泛型类的两个实例只有在它们都使用相同类型(例如 Integer)时才是相同类型。 在协议(protocol)中使用 associatedType 可能意味着一个实例化与另一个实例化不同。

使用 TurnDefinable 意味着两个实例化可以有不同的类型,编译器可能不喜欢在数组中有不同的类型(不可用)。
无法使用,因为您不能轮流对待相同的对象、调用相同的函数、访问相同的变量。
具有不同函数签名的函数不再是同一个函数。

如果编译器忽略它,您将如何编写以下内容?

for turn in turns {
    turn.answers.first!.X // ???
}

您可以使用一个空的 Answer 协议(protocol)并在其上键入 switch。也许有帮助。

protocol Answer {}

for turn in turns {
    for answer in turn.answers {
        switch answer {
        case let type1 = answer as AnswerType1:
            break //
        case let type2 = answer as AnswerType2:
            break
        default:
            fatalError("Answer type unknown \(type(of: Answer))")
        }
    }
}

关于ios - 多层次深度泛型/协议(protocol)的 Swift 泛型和协议(protocol)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51104144/

相关文章:

c# - 泛型方法正在拾取基类的类型

ios - Xcode 不允许我按住 ctrl 拖动来添加 socket

iOS:如何使用自定义信息窗口动态创建 GMSMarker?

ios - 使用 Masonry 在它的 super View 中居中 View

arrays - Swift - 检查 Array<AnyObject> 是否包含 UIColor

iphone - 无法使用 AVAudioEngine 播放声音

android - 解析嵌套的 Json 数据结构?

swift - CorePlot 与 swift : there is no yAxis. MajorIntervalLength

java - 带通配符的嵌套泛型

delphi - 在delphi中测试泛型的类型