swift 使用嵌套枚举创建问题细化

9nvpjoqh  于 2023-04-19  发布在  Swift
关注(0)|答案(2)|浏览(139)

我有一个视图控制器,它将向用户显示一个“问题下钻”,其中回答一个问题将显示基于前一个答案的下一个分配问题。
我假设嵌套枚举是一种可行的方法。下面是我目前设置的一个示例:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep)
    
    enum TechQuestionStep {
        case website(WebsiteStep), app, password, other
        
        enum WebsiteStep {
            case yesStreaming(YesStreamingStep), noStreaming
            
            enum YesStreamingStep {
                case startTime(StartTimeStep)
                
                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

func showFirstStep() {
    currentStep = SubmissionSteps.techQuestion // error here 'ViewController' has no member 'techQuestion'
}

var currentStep:SubmissionSteps? {
    didSet {
        
    }
}

var currentlyShowing:[SubmissionSteps] = [] {
    didSet {
        
    }
}

func getStepTitle(step:SubmissionSteps) -> String {
    switch step {
        
    case .techQuestion(_):
        return "Tech Question"
    case .techQuestion(.app):
        return "App" // Case is already handled by previous patterns;
    case .techQuestion(.other):
        return "Other" // Case is already handled by previous patterns;
    case .techQuestion(.password):
        return "Password" // Case is already handled by previous patterns;
    case .techQuestion(.website(_)):
        return "Website" // Case is already handled by previous patterns;
    case .techQuestion(.website(.noStreaming)):
        return "No Streaming" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(_))):
        return "Yes Streaming" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(.startTime(_)))):
        return "Start Time" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(.startTime(.endTime)))):
        return "End Time" // Case is already handled by previous patterns;
    }
}

上面的设置问题存在于getStepTitle()函数中。我不能返回父选项的标题,只能返回子选项的标题。我目前拥有的getStepTitle()函数中的switch语句显示“Case is already handled by previous patters;考虑将其删除”。
我也不能将currentStep设置为枚举中的父选项,只能设置为子选项。
要么是使用嵌套枚举的方式不适合处理这样的数据设置,要么是我对如何访问嵌套枚举中的父值以获取枚举中任何级别的当前标题有基本的误解。建议或想法?

rryofs0p

rryofs0p1#

您当前使用的枚举关联值不允许您创建“父”值。例如,currentStep = SubmissionSteps.techQuestion不起作用,因为techQuestion需要关联值。
我认为有两种解决办法。
1.使关联值为可选值。
1.创建一个新的case来表示“顶级”级别。
对于解决方案1,嵌套枚举变为:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep?)

    enum TechQuestionStep {
        case website(WebsiteStep?), app, password, other

        enum WebsiteStep {
            case yesStreaming(YesStreamingStep?), noStreaming

            enum YesStreamingStep {
                case startTime(StartTimeStep?)

                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

你可以创建一个“父”techQuestion

currentStep = SubmissionSteps.techQuestion(nil)

解决getStepTitle问题的方法是将最具体的情况放在前面,最一般的情况放在最后:

func getStepTitle(step:SubmissionSteps) -> String {
    switch step {

    case .techQuestion(.website(.yesStreaming(.startTime(.endTime)))):
        return "End Time"
    case .techQuestion(.website(.yesStreaming(.startTime(_)))):
        return "Start Time"
    case .techQuestion(.website(.yesStreaming(_))):
        return "Yes Streaming"
    case .techQuestion(.website(.noStreaming)):
        return "No Streaming"
    case .techQuestion(.website(_)):
        return "Website"
    case .techQuestion(.password):
        return "Password"
    case .techQuestion(.other):
        return "Other"
    case .techQuestion(.app):
        return "App"
    case .techQuestion(_):
        return "Tech Question"
    }
}

对于解决方案2,嵌套的枚举将变成如下所示:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep)

    enum TechQuestionStep {
        case top
        case website(WebsiteStep), app, password, other

        enum WebsiteStep {
            case top
            case yesStreaming(YesStreamingStep), noStreaming

            enum YesStreamingStep {
                case top
                case startTime(StartTimeStep)

                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

您可以使用以下命令创建一个“父”techQuestion

currentStep = SubmissionSteps.techQuestion(.top)

getStepTitle的修复是相同的。
至于你的声明:* “我假设嵌套枚举是可行的方法。"*,这完全是另外一个讨论,远远超出了这里的范围。

zphenhs4

zphenhs42#

您的第一个case,case .techQuestion(_):,将匹配任何techQuestion,无论子类型如何。一旦您有了那个case,您就不能有更多特定的case了。摆脱那个case并单独处理每个子类型,或者将您的case .techQuestion(_):移动到其他case .techQuestion() case下面,这样它就只捕获没有特定子类型之一的.techQuestion类型。
考虑这个示例项目:

import Foundation

enum Bar {
    case bar1
    case bar2
    case bar3
}

enum Foo {
    case foo1(Bar?)
    case foo2
}

let aFooBar1: Foo = .foo1(.bar1)
let aFooBar2: Foo = .foo1(.bar2)
let aFoo: Foo = .foo2


func talkboutAFoo(_ aFoo: Foo) {
    switch aFoo {
    case .foo1(nil):
        print("Foo(no bar)")
    case .foo1(.bar1):
        print("foo1(.bar1)")
    case .foo1(.bar2):
        print("foo1(.bar2)")
    case .foo1(_): // Catch-all that matches other foo1 subtypes
        print("foo1(_)")
    default:
        print("some other case")
    }

}

talkboutAFoo(Foo.foo1(.bar1))
talkboutAFoo(Foo.foo1(.bar2))
talkboutAFoo(Foo.foo1(.bar3))
talkboutAFoo(Foo.foo2)
talkboutAFoo(Foo.foo1(nil))

输出

foo1(.bar1)
foo1(.bar2)
foo1(_)
some other case
Foo(no bar)

相关问题