Swift:在 switch case-let-where 中分配给变量

标签 swift

是否可以在艺术家变量之前在 where 子句中使用它?

var artist
switch fullline {
case let path where path.hasPrefix("Monet"):
    artist = "Monet"
case let path where path.hasPrefix("Cezanne"):
    artist = "Cezanne"
default: ()
}

关闭:

case let path where { () -> Bool in let artist = "Monet"; return path.hasPrefix(artist) }:

错误:

() -> Bool' is not convertible to 'Bool'

上下文:

我有几行以艺术家姓名为前缀的自由格式文本,需要 按摩以输出一致的人类可读文本。例如

Monet : Snow at Argenteuil 02, 1874
Monet - Snow at Argenteuil, 1874, 3rd Floor Collections
Monet, Claude - 1875, Snow in Argenteuil
Cezzane - Vase of Flowers, 1880-81, print
Cezzane, Paul 1900-1903 Vase of Flowers
Cezzane - Vase with Flowers, 1895-1896

会有一个代码片段,进行详细的处理/分类 对于每个艺术家。因此,处理逻辑取决于艺术家。

我想定义类似于下面的结构

switch fullline
hasPrefix(artist = "Monet")  
    -> code logic 1
       get_birthday(artist)

hasPrefix(artist = "Cezzane")
    -> code logic 2
       get_birthday(artist)

最佳答案

稍微修改一下Alexander的结构,你可以这样写:

struct PrefixMatcherWithHandler {
    var handler: (String)->Void
    var string: String
    init(_ string: String, handler: @escaping (String)->Void) {
        self.string = string
        self.handler = handler
    }

    static func ~= (prefix: String, matcher: PrefixMatcherWithHandler) -> Bool {
        if matcher.string.hasPrefix(prefix) {
            matcher.handler(prefix)
            return true
        } else {
            return false
        }
    }
}

var fullline: String = "Monet, Claude"

var artist: String? = nil

let matcher = PrefixMatcherWithHandler(fullline) {str in
    artist = str
}

switch matcher {
case "Monet":
    break
case "Cezanne":
    break
default: break
}
print(artist ?? "") //->Monet

但是在像 ~= 这样的 bool 运算符中有一些副作用会降低你的代码的可读性,并且很容易产生意想不到的结果。

如果你只是想减少对同一事物的一些冗余引用,switch-statement 可能不是一个好的工具。

例如,您可以在不定义特定匹配器类型的情况下获得相同的结果:

var fullline: String = "Monet, Claude"

var artist: String? = nil

if let match = ["Monet", "Cezanne"].first(where: {fullline.hasPrefix($0)}) {
    artist = match
}
print(artist ?? "") //->Monet

ADDED 问题的更新部分

以下代码的行为与前缀匹配略有不同,但我相信您不想将 "Mon" 匹配到行 Monet, Claude - 1875, Snow in Argenteuil.

extension String {
    var firstWord: String? {
        var result: String? = nil
        enumerateSubstrings(in: startIndex..<endIndex, options: .byWords) {str, _, _, stop in
            result = str
            stop = true
        }
        return result
    }
}

func get_birthday(_ artist: String) {
    //What do you want to do?
    print(artist)
}

var fullline: String = "Monet, Claude - 1875, Snow in Argenteuil"

switch fullline.firstWord {
case let artist? where artist == "Monet":
    //code dedicated for "Monet"
    get_birthday(artist)
case let artist? where artist == "Cezanne":
    //code dedicated for "Cezanne"
    get_birthday(artist)
default:
    break
}

当您可以检索适合于 switch 语句的数据时,代码将更加直观和可读。

关于Swift:在 switch case-let-where 中分配给变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45396139/

相关文章:

ios - 如何根据用户输入更新约束

swift - 自定义 UIButton 作为导航项后退按钮工作,但不显示

ios - 如何设置 MDCMultilineTextField 中 float 占位符的正常颜色?

ios - 将文档从 iMessage 导入应用程序 - 删除放置在 "Inbox"中的临时文件

ios - 如何检查哪个collectionview是否在快速滚动

swift - 在没有 WeekCalendarUnit 的情况下获取一周的第一天

ios - 可选值上的 Swift KeyPath

ios - 我在 Storyboard中创建了一个按钮,并以编程方式设置图像,但出现错误,为什么?

swift - 关闭 Swiftui View 后如何清理环境对象?

swift 3 : Int is not convertible to Bool in bitwise operation