首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Swift:在开关中赋值给变量

Swift:在开关中赋值给变量
EN

Stack Overflow用户
提问于 2017-07-30 03:43:57
回答 3查看 13.3K关注 0票数 3

在where子句中使用艺术家变量之前,是否可以对其进行赋值?

代码语言:javascript
复制
var artist
switch fullline {
case let path where path.hasPrefix("Monet"):
    artist = "Monet"
case let path where path.hasPrefix("Cezanne"):
    artist = "Cezanne"
default: ()
}

闭包:

代码语言:javascript
复制
case let path where { () -> Bool in let artist = "Monet"; return path.hasPrefix(artist) }:

错误:

() ->布尔不可转换为“Bool”

上下文:

我有以艺术家名字作为前缀的自由格式文本行,需要按摩才能输出一致的、具有人类可读性的文本。例如:

莫奈:阿根廷的雪02,1874年的莫奈-阿根廷的雪,1874年,三楼收藏莫奈,克劳德-1875年,雪在阿根廷的Cezzane -花瓶,1880-81,印刷Cezzane,保罗1900-1903年的花卉花瓶,Cezzane -花瓶,1895-1896

将有一个代码片段对每个艺术家执行详细的处理/分类。因此,处理逻辑依赖于艺术家。

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

代码语言:javascript
复制
switch fullline
hasPrefix(artist = "Monet")  
    -> code logic 1
       get_birthday(artist)

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

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-30 18:50:57

稍微修改一下Alexander的结构,您就可以编写如下内容:

代码语言:javascript
复制
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

但是,在布尔运算符(如~= )中产生一些副作用会降低代码的可读性,并且很容易产生意想不到的结果。

如果您只想减少对同一件事情的一些冗余引用,那么switch-statement可能不是一个很好的工具。

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

代码语言:javascript
复制
var fullline: String = "Monet, Claude"

var artist: String? = nil

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

为问题的更新部分添加了

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

代码语言:javascript
复制
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-statement的数据时,代码将更加直观和可读性更强。

票数 3
EN

Stack Overflow用户

发布于 2017-07-30 06:29:30

你给出的闭包是一个布尔值。不确定为什么要这样做,但可以通过使用()调用闭包来使其工作。

代码语言:javascript
复制
var artist
switch fullline {
case let path where { () -> Bool in let artist = "Monet"; return path.hasPrefix(artist) }():
    artist = "Monet"
case let path where path.hasPrefix("Cezanne"):
    artist = "Cezanne"
default: ()
}

我会这样做:

代码语言:javascript
复制
import Foundation

struct PrefixMatcher {
    let string: String
    init(_ string: String) { self.string = string }

    static func ~= (prefix: String, matcher: PrefixMatcher) -> Bool {
        return matcher.string.hasPrefix(prefix)
    }
}

extension String {
    var prefix: PrefixMatcher { return PrefixMatcher(self) }
}


let fullline = "Monet 123456789"

let artist: String?

switch fullline.prefix {
    case "Monet": artist = "Monet"
    case "Cezanne": artist = "Cezanne"
    default: artist = nil
}

print(artist as Any)

更普遍的解决办法:

代码语言:javascript
复制
import Foundation

struct PredicateMatcher<Pattern> {
    typealias Predicate = (Pattern) -> Bool

    let predicate: Predicate

    static func ~=(pattern: Pattern,
                   matcher: PredicateMatcher<Pattern>) -> Bool {
        return matcher.predicate(pattern)
    }
}

extension String {
    var prefix: PredicateMatcher<String> {
        return PredicateMatcher(predicate: self.hasPrefix)
    }
}
票数 2
EN

Stack Overflow用户

发布于 2020-02-02 06:44:39

您可以通过切换您的枚举和可选的元组来实现这一点。可选也是一个枚举,所以您可以同时切换它们。

代码语言:javascript
复制
enum SomeSnum {
   case a, b, c
}

let someString: String? = "something"
let esomeEnum = SomeSnum.b

switch(esomeEnum, someString) {
case (.b, .some(let unwrappedSomething)) where unwrappedSomething.hasPrefix("so"):
    print("case .b, \(unwrappedSomething) is unwrapped, and it has `so` prefix")

case (.a, .none):
    print("case .a, and optional is nil")

default:
    print("Something else")
}

您还可以执行if语句。

代码语言:javascript
复制
if case let (.b, .some(unwrappedSomething)) = (esomeEnum, someString), unwrappedSomething.hasPrefix("so") {

} else if case (.a, .none) = (esomeEnum, someString) {

} else {

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45396139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档