我有一个协议BluetoothLeAdvertiser
,并且我希望遵循几种不同的Scale结构(即BluetoothLeAdvertiser
,ScaleDetails
等)。然后,我想要一个不同的协议MajorScale
,该协议具有类型DiminishedScale
的变量ComboChord
,根据其他变量的不同,其规模也不同。问题是我无法在scale
中将ScaleDetails
变量分配为类型scale
,因为我不知道如何在不使用关联类型的情况下编写协议。
每个比例尺使用不同的模式枚举(例如,ComboChord
的{{1}}和ScaleDetails
的{{1}})。每个标度都有返回该特定标度结构的一个或多个实例的函数。因此,如果在我的Mode.SevenDeg
协议中不使用泛型,我将看不到前进的道路。我试图在不使用类的情况下编写此代码,但在必要时愿意使用它们。我也确实在尝试避免对秤进行类型转换,因为我不想每次调用它时都必须列出每种秤的可能性。我该如何解决?
MajorScale
Mode.TwoDeg
DiminishedScale
ScaleDetails
protocol ScaleDetails {
associatedtype ScaleMode where ScaleMode: RawRepresentable
associatedtype T
//...
var root: Root { get set }
var mode: ScaleMode { get set }
//...
init(_ root: KeyName.Root, mode: ScaleMode)
func translated(by offset: Int) -> T
func enharmSwapped() -> T
//...
mutating func switchMode(mode: ScaleMode)
func getParallelModes(root: KeyName.Root) -> [T]
func getParentModes() -> [T]
}
protocol ComboChord {
var scale: ScaleDetails // doesn't work
static var validCombos: [[Int]] { get }
var quality: Suffix { get }
var uprStrNotes: [Int] { get }
/*
error: "Protocol can only be used as a generic constraint
because it has Self or associatedType requirements"
*/
}
enum Mode {
enum TwoDeg: Int, CaseIterable, ModeProtocol {
case one = 0, two
//...
}
enum SevenDeg: Int, CaseIterable, ModeProtocol {
case one = 0, two, three, four, five, six, seven
//...
}
}
(大量缩减长度,原始长度约为1400行)
struct MajorScale: ScaleDetails {
var root: Root
var mode: Mode.SevenDeg
//...
init(_ root: KeyName.Root, mode: Mode.SevenDeg = .one) {
self.root = Root(root)
self.mode = mode
self.enharm = root.r.enharm
}
func translated(by offset: Int) -> MajorScale {
//...do things to the scale
return MajorScale(newRootKey, mode: mode)
}
//...
mutating func switchMode(mode: Mode.SevenDeg) {
self.mode = mode
}
//...
func enharmSwapped() -> MajorScale {
//...do things to the scale
return MajorScale(newRootKey, mode: mode)
}
func getParallelModes(root: KeyName.Root) -> [MajorScale] {
return Mode.SevenDeg.allCases.map {MajorScale(root, mode: $0)}
}
func getParentModes() -> [MajorScale] {
//...code to get array of scales
return parentModes
}
}
答案 0 :(得分:1)
不确定是否适合您的用法,但是也许您也可以使ComboChord
通用
protocol ComboChord {
associatedtype Scale: ScaleDetails
var scale: Scale { get }
}
然后像这样使用它
struct Chord: ComboChord {
var scale: DiminishedScale
}