我正计划为芝加哥儿童制作一个闪存卡应用程序,只要他们能够遵循相同的协议,就可以提出很多问题。理想情况下,会有许多不同难度的游戏,并且视图将能够使用所有游戏,因为所有游戏都遵循相同的协议。我希望每个转弯都有能力采用完全不同的结构,只要它是相等的即可。
我觉得我已经接近了,但是我无法终生解决如何让游戏获取任何数据而又不会出错的感觉……我觉得我已经接近了,但是可以不能超过这个减速带。
我不断收到错误消息,例如“ TurnDefinable只能用作通用约束,因为它具有Self或associate类型要求”
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])
我好亲近!感谢到目前为止的所有帮助!
答案 0 :(得分:0)
我有个主意,但我不确定。
如果泛型类的两个实例化都使用相同的类型(例如整数),则它们只有相同的类型。 在协议中具有associatedType可能意味着一个实例不能与另一个实例相同地使用。
使用TurnDefinable意味着两个实例化可以具有不同的类型,并且编译器可能不希望数组中具有不同的类型(不可用)。
无法使用,因为您不能一视同仁,调用相同的函数,访问相同的变量。
具有不同功能签名的功能不再是同一功能。
如果编译器只是忽略以下内容,您将如何编写?
for turn in turns {
turn.answers.first!.X // ???
}
您可以使用一个空的Answer协议并在其上键入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))")
}
}
}
答案 1 :(得分:0)
您不能拥有类型为TurnDefinable
的数组,因为您已经看到它是具有关联类型的协议。
您需要调整GameDefinable
协议,使其具有自己的关联类型,可以将其用作数组的类型:
protocol GameDefinable {
associatedtype TurnType: TurnDefinable
var turns: [TurnType] { get }
}
然后,您可以在Game
类中添加一个通用参数,该通用参数将用作GameDefinable
协议的关联类型(您也可以跳过该通用参数,并使用特定类型声明数组例如Turn<ExampleOfAnAnswerStruct>
(如果您想将游戏限制为某种类型)
class Game<T: TurnDefinable>: GameDefinable {
var turns: [T]
init(turns: [T]) {
self.turns = turns
}
}