Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 从枚举中选择随机值_Swift_Enums - Fatal编程技术网

Swift 从枚举中选择随机值

Swift 从枚举中选择随机值,swift,enums,Swift,Enums,从给定枚举中选择随机值 public class SwiftConfettiView: UIView { public enum ConfettiType { case confetti case triangle case star case diamond case image(UIImage) } //在其他类中的用法 confettiView.type = .confetti 想

从给定枚举中选择随机值

public class SwiftConfettiView: UIView {

    public enum ConfettiType {
        case confetti
        case triangle
        case star
        case diamond
        case image(UIImage)
    }
//在其他类中的用法

    confettiView.type = .confetti
想随机设置彩色纸屑视图三角形、星形、菱形、彩色纸屑

//这行不通

confetti.type =  ConfettiType.allCases.randomElement()!
类型“SwiftConfettiView.ConfettiType”没有成员“allCases”

//所以,将所有五彩纸屑放入数组列表并从那里加载

var confettiList = [SwiftConfettiView.ConfettiType.confetti
    , SwiftConfettiView.ConfettiType.diamond
    ,        SwiftConfettiView.ConfettiType.triangle
    ,        SwiftConfettiView.ConfettiType.star
]

它工作正常


这种方法是正确的还是错误的?

这里您的枚举是关联类型。所以,如果类型为image,则必须提供一个image作为参数。我考虑了一个默认图像

extension ConfettiType: CaseIterable {
    static var allCases: [ConfettiType] {
        let img: UIImage = UIImage(named: "default_image")! // change as your expectation
        return [.confetti, .triangle, .star, .diamond, .image(img)]
    }    
}
let randomEnum = ConfettiType.allCases.randomElement()

否则,如果您的图像类型类似于此
image(UIImage?
),那么我们可以将
nil
作为默认值。在这种情况下会更方便。

这里您的枚举是关联类型。所以,如果类型为image,则必须提供一个image作为参数。我考虑了一个默认图像

extension ConfettiType: CaseIterable {
    static var allCases: [ConfettiType] {
        let img: UIImage = UIImage(named: "default_image")! // change as your expectation
        return [.confetti, .triangle, .star, .diamond, .image(img)]
    }    
}
let randomEnum = ConfettiType.allCases.randomElement()

否则,如果您的图像类型类似于此
image(UIImage?
),那么我们可以将
nil
作为默认值。在这种情况下会更方便。

@Alexander在评论中指出了您的问题:您的问题是您需要符合
CaseIterable
才能访问
所有案例
,并且只有在
枚举
没有关联值的情况下才有效(因为无法枚举所有可能的
UIImage
s)

您的变通方法很好,可以通过利用Swift的类型推断使其变得更好

您可以在枚举类中添加一个
randomChoice(from:)
函数,让调用者指定要从中选择的项目。由于类型推断,您可以在不完全限定它们的情况下指定案例(例如
。五彩纸屑
。三角形
就足够了)

以下是一个完整的示例:

public class SwiftConfettiView: UIView {

    public enum ConfettiType {
        case confetti
        case triangle
        case star
        case diamond
        case image(UIImage)

        static func randomChoice(from choices: ConfettiType...) -> ConfettiType {
            return choices.randomElement()!
        }
    }

    func test() {
        for _ in 1...10 {
            let choice = ConfettiType.randomChoice(from: .confetti, .triangle, .star, .diamond)
            print(choice)
        }
    }
}

SwiftConfettiView().test()
注意事项:

  • 或者,您可以使用
    randomChoice
    take
    [ConfettitType]
    。在这种情况下,您需要决定如何处理空数组(或者返回可选值,以便可以为空数组返回
    nil
    ,或者为该情况提供默认值,例如
    .confetti

    使用数组可以提供默认值,例如:

    static func randomChoice(from choices: [ConfettiType] = [.confetti, .triangle, .star, .diamond]) -> ConfettiType {
        return choices.randomElement() ?? .confetti
    }
    
    例如:

    // take the default values
    let choice = ConfettiType.randomChoice()
    
    // specify specific choices
    let choice = ConfettiType.randomChoice(from: [.star, .diamond])
    
  • 如果您总是只想从这4个枚举值中进行选择,您可以让
    randomChoice
    不带参数,只需硬编码这4个值中的选择。在这种情况下,
    randomChoice
    可以实现为计算属性:

    static var randomChoice: ConfettiType { return [.confetti, .triangle, .star, .diamond].randomElement()! }
    
    并这样称呼:

    let choice = ConfettiType.randomChoice
    

@Alexander在评论中指出了您的问题:您的问题是您需要遵守
CaseIterable
才能访问
所有案例
,并且只有当您的
enum
没有关联的值时(因为无法枚举所有可能的
UIImage

您的变通方法很好,可以通过利用Swift的类型推断使其变得更好

您可以在枚举类中添加一个
randomChoice(from:)
函数,让调用者指定要从中选择的项目。由于类型推断,您可以在不完全限定它们的情况下指定案例(例如
。五彩纸屑
。三角形
就足够了)

以下是一个完整的示例:

public class SwiftConfettiView: UIView {

    public enum ConfettiType {
        case confetti
        case triangle
        case star
        case diamond
        case image(UIImage)

        static func randomChoice(from choices: ConfettiType...) -> ConfettiType {
            return choices.randomElement()!
        }
    }

    func test() {
        for _ in 1...10 {
            let choice = ConfettiType.randomChoice(from: .confetti, .triangle, .star, .diamond)
            print(choice)
        }
    }
}

SwiftConfettiView().test()
注意事项:

  • 或者,您可以使用
    randomChoice
    take
    [ConfettitType]
    。在这种情况下,您需要决定如何处理空数组(或者返回可选值,以便可以为空数组返回
    nil
    ,或者为该情况提供默认值,例如
    .confetti

    使用数组可以提供默认值,例如:

    static func randomChoice(from choices: [ConfettiType] = [.confetti, .triangle, .star, .diamond]) -> ConfettiType {
        return choices.randomElement() ?? .confetti
    }
    
    例如:

    // take the default values
    let choice = ConfettiType.randomChoice()
    
    // specify specific choices
    let choice = ConfettiType.randomChoice(from: [.star, .diamond])
    
  • 如果您总是只想从这4个枚举值中进行选择,您可以让
    randomChoice
    不带参数,只需硬编码这4个值中的选择。在这种情况下,
    randomChoice
    可以实现为计算属性:

    static var randomChoice: ConfettiType { return [.confetti, .triangle, .star, .diamond].randomElement()! }
    
    并这样称呼:

    let choice = ConfettiType.randomChoice
    

不要使用SQL风格的前导逗号。这是SQL可怕的设计的一个支柱,它不允许在列表末尾使用多余的逗号。Swift没有这个问题,所以它不需要这个支柱。只需在每个列表项的末尾使用逗号。这里的问题是,您需要遵守
caseitrable
来访问
所有案例,并且仅当枚举没有关联的值时才有效(因为无法枚举所有可能的
UIImage
s。我不确定最好的解决方法是什么。不要使用SQL样式的前导逗号。这是SQL可怕的设计的一个支柱,它不允许在列表末尾使用多余的逗号。Swift没有这个问题,所以它不需要拐杖。只要在我看到的每个列表末尾都放逗号就行了。)这里的问题是,您需要遵守
caseitrable
才能访问
所有案例
,并且只有当您的枚举没有关联的值时,这才有效(因为无法枚举所有可能的
UIImage
。我不确定最佳解决方法是什么。