- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个协议(protocol) ScaleDetails
,我希望几个不同的 Scale 结构符合(即 MajorScale
、DiminishedScale
等)。然后我想要一个不同的协议(protocol),ComboChord
,它有一个类型为 ScaleDetails
的变量 scale
,这将是一个不同的规模取决于另一个别处变量。问题是我无法将 ComboChord
中的 scale
var 分配给类型 ScaleDetails
因为我不知道如何在没有使用关联类型。
每个不同的比例使用不同的模式枚举(例如 Mode.SevenDeg
用于 MajorScale
和 Mode.TwoDeg
用于 DiminishedScale
)。每个比例都有返回该特定比例结构的一个或多个实例的函数。因此,如果不在我的 ScaleDetails
协议(protocol)中使用泛型,我看不到前进的方向。如果可能的话,我试图在不使用类的情况下编写它,但如果有必要,我愿意使用它们。我也确实在努力避免对我的比例进行类型转换,因为我不想每次调用它时都必须列出每个比例可能性。我该如何解决这个问题?
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
//...
}
}
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
}
}
struct DiminishedScale: ScaleDetails {
var root: Root
var mode: Mode.TwoDeg
//...
init(_ root: KeyName.Root, mode: Mode.TwoDeg = .one) {
self.root = Root(root)
self.mode = mode
self.enharm = root.r.enharm
}
func translated(by offset: Int) -> DiminishedScale {
//...do things to the scale
return MajorScale(newRootKey, mode: mode)
}
//...
mutating func switchMode(mode: Mode.TwoDeg) {
self.mode = mode
}
//...
func enharmSwapped() -> DiminishedScale {
//...do things to the scale
return MajorScale(newRootKey, mode: mode)
}
func getParallelModes(root: KeyName.Root) -> [DiminishedScale] {
return Mode.TwoDeg.allCases.map {DiminishedScale(root, mode: $0)}
}
func getParentModes() -> [DiminishedScale] {
//...code to get array of scales
return parentModes
}
}
enum KeyName: String, CaseIterable {
case c = "C"
case d = "D"
case e = "E"
case f = "F"
case g = "G"
case a = "A"
case b = "B"
case cB = "C\u{266D}"
case dB = "D\u{266D}"
case eB = "E\u{266D}"
case fB = "F\u{266D}"
case gB = "G\u{266D}"
case aB = "A\u{266D}"
case bB = "B\u{266D}"
case cSh = "C\u{266F}"
case dSh = "D\u{266F}"
case eSh = "E\u{266F}"
case fSh = "F\u{266F}"
case gSh = "G\u{266F}"
case aSh = "A\u{266F}"
case bSh = "B\u{266F}"
case c_bb = "C\u{266D}\u{266D}"
case d_bb = "D\u{266D}\u{266D}"
case e_bb = "E\u{266D}\u{266D}"
case f_bb = "F\u{266D}\u{266D}"
case g_bb = "G\u{266D}\u{266D}"
case a_bb = "A\u{266D}\u{266D}"
case b_bb = "B\u{266D}\u{266D}"
case cX = "Cx"
case dX = "Dx"
case eX = "Ex"
case fX = "Fx"
case gX = "Gx"
case aX = "Ax"
case bX = "Bx"
enum Root {
case c, d, e, f, g, a, b
case cB, dB, eB, fB, gB, aB, bB
case cSh, dSh, eSh, fSh, gSh, aSh, bSh
var r: KeyName {
switch self {
case .c:
return .c
case .d:
return .d
case .e:
return .e
case .f:
return .f
case .g:
return .g
case .a:
return .a
case .b:
return .b
case .cB:
return .cB
case .dB:
return .dB
case .eB:
return .eB
case .fB:
return .fB
case .gB:
return .gB
case .aB:
return .aB
case .bB:
return .bB
case .cSh:
return .cSh
case .dSh:
return .dSh
case .eSh:
return .eSh
case .fSh:
return .fSh
case .gSh:
return .gSh
case .aSh:
return .aSh
case .bSh:
return .bSh
}
}
init(_ key: KeyName) {
switch key {
case .c:
self = .c
case .d:
self = .d
case .e:
self = .e
case .f:
self = .f
case .g:
self = .g
case .a:
self = .a
case .b:
self = .b
case .cB:
self = .cB
case .dB:
self = .dB
case .eB:
self = .eB
case .fB:
self = .fB
case .gB:
self = .gB
case .aB:
self = .aB
case .bB:
self = .bB
case .cSh:
self = .cSh
case .dSh:
self = .dSh
case .eSh:
self = .eSh
case .fSh:
self = .fSh
case .gSh:
self = .gSh
case .aSh:
self = .aSh
case .bSh:
self = .bSh
default:
self = .c
}
}
}
//...
}
struct Root: Note {
var noteName: String {
return key.name
}
var rootKey: KeyName.Root
var noteNum: NoteNum
var num: Int {return noteNum.num}
var enharm: Enharmonic
var degName: (name: DegName.Name, short: DegName.Short, long: DegName.Long) {
return (name: DegName.Name(.root), short: DegName.Short(.root), long: DegName.Long(.root))
}
var key: KeyName
init(noteNum: NoteNum = .zero, enharm: Enharmonic = .flat) {
self.noteNum = noteNum
self.enharm = enharm
var ks: KeySwitch {
return KeySwitch(enharm: enharm)
}
var rs: RootSwitch {
return RootSwitch(enharm: enharm)
}
switch noteNum {
case .zero:
self.key = ks.pickKey(.c, .bSh)
self.rootKey = rs.pickRoot(.c, .bSh)
case .one:
self.key = ks.pickKey(.dB, .cSh)
self.rootKey = rs.pickRoot(.dB, .cSh)
case .two:
self.key = .d
self.rootKey = .d
case .three:
self.key = ks.pickKey(.eB, .dSh)
self.rootKey = rs.pickRoot(.eB, .dSh)
case .four:
self.key = ks.pickKey(.fB, .e)
self.rootKey = rs.pickRoot(.fB, .e)
case .five:
self.key = ks.pickKey(.f, .eSh)
self.rootKey = rs.pickRoot(.f, .eSh)
case .six:
self.key = ks.pickKey(.gB, .fSh)
self.rootKey = rs.pickRoot(.gB, .fSh)
case .seven:
self.key = .g
self.rootKey = .g
case .eight:
self.key = ks.pickKey(.aB, .gSh)
self.rootKey = rs.pickRoot(.aB, .gSh)
case .nine:
self.key = .a
self.rootKey = .a
case .ten:
self.key = ks.pickKey(.bB, .aSh)
self.rootKey = rs.pickRoot(.bB, .aSh)
case .eleven:
self.key = ks.pickKey(.cB, .b)
self.rootKey = rs.pickRoot(.cB, .b)
}
}
init(_ key: KeyName.Root) {
self.key = key.r
self.rootKey = key
self.noteNum = self.key.noteNum
self.enharm = self.key.enharm
}
mutating func kSW(ks: KeySwitch) {
switch noteNum {
case .zero:
self.key = ks.pickKey(.c, .bSh)
case .one:
self.key = ks.pickKey(.dB, .cSh)
case .two:
self.key = .d
case .three:
self.key = ks.pickKey(.eB, .dSh)
case .four:
self.key = ks.pickKey(.fB, .e)
case .five:
self.key = ks.pickKey(.f, .eSh)
case .six:
self.key = ks.pickKey(.gB, .fSh)
case .seven:
self.key = .g
case .eight:
self.key = ks.pickKey(.aB, .gSh)
case .nine:
self.key = .a
case .ten:
self.key = ks.pickKey(.bB, .aSh)
case .eleven:
self.key = ks.pickKey(.cB, .b)
}
}
mutating func swapEnharm() {
enharm = enharm == .flat ? .sharp : .flat
kSW(ks: KeySwitch(enharm: enharm))
rootKey = KeyName.Root(key)
}
func enharmSwapped() -> Root {
return Root(noteNum: noteNum, enharm: enharm == .flat ? .sharp : .flat)
}
}
(大幅缩减了长度……原来大约有 1400 行)
struct DetailChord {
enum DCType {
case dom7, ma7, mi7, mi7b5, dim7, error
}
init(resultChord: ResultChord?, verdict: Verdict = .goodToGo) {
self.verdict = verdict
self.dRC = resultChord
if let rc = dRC {
switch rc.baseChord.lowerQual {
case .dom7:
dct = .dom7
case .ma7:
dct = .ma7
case .mi7:
dct = .mi7
case .mi7_b5:
dct = .mi7b5
case .dim7:
dct = .dim7
}
} else {
dct = .error
}
}
var dct: DCType
var dRC: ResultChord?
var verdict: Verdict
var validCombos: [[[Int]]] {
switch dct {
case .dom7:
return Dom7.validCombos
case .ma7:
return Maj7.validCombos
case .mi7:
return Min7.validCombos
case .mi7b5:
return Min7_b5.validCombos
case .dim7:
return Dim7.validCombos
default:
return [[[]]]
}
}
var tension: [[Int]] {
switch dct {
case .dom7:
return Dom7.tension
case .ma7:
return Maj7.tension
case .mi7:
return Min7.tension
case .mi7b5:
return Min7_b5.tension
case .dim7:
return Dim7.tension
default:
return [[]]
}
}
func qualSwitcher(validCombos: [[[Int]]], degrees: [Int]) -> Int {
var validCombosIndex = Int()
for (index, combos) in validCombos.enumerated() {
if combos.contains(degrees) {
validCombosIndex = index
break
}
}
return validCombosIndex
}
var chord: ComboChord {
mutating get {
if let rc = dRC {
let degrees = rc.degrees
let degreesUnsorted = rc.degreesUnsorted
let baseChord = rc.baseChord
let degSet = rc.degSet
var validCombosIndex = Int()
func tensionOrGoodToGo(getComboChord: GetComboChord) -> ComboChord {
if !tension.contains(degrees) { // good to go!
verdict = .goodToGo
validCombosIndex = qualSwitcher(validCombos: validCombos, degrees: degrees)
return getComboChord(degSet, validCombosIndex)
} else { // tension!
verdict = .tension
if let tensionQual = rc.baseChord.qualSuffix as? Suffix.Lower {
return TensionChord(tensionQual, rc.degreesUnsorted)
} else {
return ErrorChord()
}
}
}
switch dct {
case .dom7:
return tensionOrGoodToGo(getComboChord: Dom7.getComboChord(degSet:validCombosIndex:))
case .ma7:
return tensionOrGoodToGo(getComboChord: Maj7.getComboChord(degSet:validCombosIndex:))
case .mi7:
return tensionOrGoodToGo(getComboChord: Min7.getComboChord(degSet:validCombosIndex:))
case .mi7b5:
return tensionOrGoodToGo(getComboChord: Min7_b5.getComboChord(degSet:validCombosIndex:))
case .dim7:
return tensionOrGoodToGo(getComboChord: Dim7.getComboChord(degSet:validCombosIndex:))
case .error:
return ErrorChord()
}
} else {
print("rc not found!")
dct = .error
return ErrorChord()
}
}
}
struct Dom7: DetailChordType {
static let matches = Mixolydian.validCombos + LydianDom.validCombos + HalfWholeDim.validCombos + AltP5.validCombos + MelodicMinor_Chord.validCombos + HexatonicSh9Sh11_Chord.validCombos + HalfWholeDimFlat13_Chord.validCombos
static let validCombos: [[[Int]]] = [Mixolydian.validCombos, LydianDom.validCombos, HalfWholeDim.validCombos, AltP5.validCombos, MelodicMinor_Chord.validCombos, HexatonicSh9Sh11_Chord.validCombos, HalfWholeDimFlat13_Chord.validCombos]
static let tension = [[0, 1, 4, 5, 7, 8, 10], [0, 4, 7, 8, 10, 11], [0, 4, 5, 7, 9, 10], [0, 2, 4, 7, 10, 11], [0, 2, 4, 5, 7, 10], [0, 3, 4, 6, 7, 10, 11], [0, 2, 4, 5, 7, 9, 10], [0, 4, 7, 10, 11], [0, 4, 5, 7, 8, 10], [0, 3, 4, 7, 8, 10, 11], [0, 1, 4, 5, 7, 10], [0, 2, 4, 6, 7, 10, 11], [0, 1, 4, 5, 7, 9, 10], [0, 3, 4, 7, 10, 11], [0, 2, 4, 5, 7, 8, 10], [0, 4, 5, 7, 8, 10, 11], [0, 2, 4, 7, 8, 10, 11], [0, 2, 4, 5, 7, 10, 11], [0, 3, 4, 5, 7, 10], [0, 4, 5, 7, 10], [0, 4, 6, 7, 10, 11], [0, 4, 7, 9, 10, 11], [0, 1, 4, 6, 7, 10, 11]]
static let tensionTones = [5, 11]
static func getComboChord(degSet: Set<Int>, validCombosIndex: Int) -> ComboChord {
switch validCombosIndex {
case 0: // mixolydian
switch degSet {
case let degs where degs.isSuperset(of: Dom7.Mixolydian.XIII.uprStrNotes): // 13
return Dom7.Mixolydian.xiii
// sus4/sus2 on 2nd, sus2 on 5th, min or sus 4 triad on maj6
case let degs where degs.isSuperset(of: Dom7.Mixolydian.Nine.uprStrNotes): // 9
// sus2 on root, min or sus4 triad on p5
return Dom7.Mixolydian.nine
default: // 7
//maj triad on root, dim triad on 3rd
return Dom7.Mixolydian.seven
}
case 1: // lydian dominant
// similar structure to case 0
case 2: // half-whole dim
// similar structure to case 0
case 3:
// similar structure to case 0
case 4: // 5th mode melodic minor
// similar structure to case 0
case 5: // hexatonicSh9Sh11
// similar structure to case 0
default: // half-whole dim(b13)
// similar structure to case 0
}
}
var chordType: ComboChord = Mixolydian.seven
enum Mixolydian: ComboChord {
case seven, nine, xiii
var scale: ScaleDetails {
switch self {
default:
return Major(mode: .five, modeOffset: 0)
}
}
static let validCombos: [[Int]] = Seven.validCombos + Nine.validCombos + XIII.validCombos
struct Seven {
static let validCombos = [[0, 4, 7, 10]]
static let uprStrNotes: [Int] = []
}
struct Nine {
static let validCombos: [[Int]] = [[0, 2, 4, 7, 10]]
static let uprStrNotes: [Int] = [2]
}
struct XIII {
static let validCombos: [[Int]] = [[0, 2, 4, 7, 9, 10], [0, 4, 7, 9, 10]]
static let uprStrNotes: [Int] = [9]
}
var quality: Suffix {
switch self {
case .seven:
return .sev
case .nine:
return .nine
case .xiii:
return .xiii
}
}
var uprStrNotes: [Int] {
switch self {
case .seven:
return Seven.uprStrNotes
case .nine:
return Nine.uprStrNotes
case .xiii:
return XIII.uprStrNotes
}
}
}
enum LydianDom: ComboChord {
// same structure as Mixolydian
}
enum HalfWholeDim: ComboChord {
// same structure as Mixolydian
}
enum AltP5: ComboChord {
// same structure as Mixolydian
}
enum HexatonicSh9Sh11_Chord: ComboChord {
// same structure as Mixolydian
}
enum MelodicMinor_Chord: ComboChord {
// same structure as Mixolydian
}
enum HalfWholeDimFlat13_Chord: ComboChord {
// same structure as Mixolydian
}
}
struct Maj7: DetailChordType {
// same structure as Dom7
}
struct Min7: DetailChordType {
// same structure as Dom7
}
struct Min7_b5: DetailChordType {
// same structure as Dom7
}
struct Dim7: DetailChordType {
// same structure as Dom7
}
}
最佳答案
不确定它是否适合您的使用,但也许您也可以使 ComboChord
通用
protocol ComboChord {
associatedtype Scale: ScaleDetails
var scale: Scale { get }
}
然后像这样使用它
struct Chord: ComboChord {
var scale: DiminishedScale
}
关于swift - 有什么方法可以在不使用泛型的情况下编写我的协议(protocol),或者使用关联类型的其他解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56381158/
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!