[英]Swift Generics and Protocol issues for multi-level-deep generics/protocol
我正計划為芝加哥兒童制作一個閃存卡應用程序,只要他們能夠遵守相同的協議,它就可以提出很多問題。 理想情況下,會有許多不同難度的游戲,並且視圖將能夠使用所有游戲,因為所有游戲都遵循相同的協議。 我希望每個轉彎都有能力采用完全不同的結構,只要它是相等的即可。
我覺得我已經接近了,但是我無法終生解決如何讓游戲獲取任何數據而又不會出錯的感覺……我覺得我已經接近了,但是無法過去這個減速帶。
我不斷收到諸如“ TurnDefinable只能用作通用約束,因為它具有自定義或關聯類型要求”之類的錯誤。
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])
我好親密! 感謝到目前為止的所有幫助!
我有個主意,但我不確定。
如果泛型類的兩個實例化都使用相同的類型(例如整數),則它們只有相同的類型。 在協議中具有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))")
}
}
}
您不能擁有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
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.