首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >斯威夫特。带有可选RawValue的RawRepresentable初始化

斯威夫特。带有可选RawValue的RawRepresentable初始化
EN

Stack Overflow用户
提问于 2017-02-22 00:59:27
回答 3查看 1.2K关注 0票数 2

我正在尝试为RawRepresentable创建一个带有可选参数的通用的失败初始化器,基本上就是这个https://www.natashatherobot.com/swift-failable-enums-with-optionals/

提出了几种方法,其中一种是这样(编辑:在第二个子句中修复了let ):

代码语言:javascript
复制
extension RawRepresentable {

    init?(rawValue optionalRawValue: RawValue?) {

        guard let rawValue = optionalRawValue, let value = Self(rawValue: rawValue) else { return nil }

        self = value
    }
} 

从这里开始https://gist.github.com/okla/e5dd8fbb4e604dabcdc3

我不知道它是否能在Swift 2上运行,但我不能在Swift 3上编译它。我得到:

代码语言:javascript
复制
Command failed due to signal: Segmentation fault: 11

有没有办法让它工作呢?

附注:我从这篇文章和评论中了解到了其他方法。

编辑:修复了损坏的复制/粘贴代码。

EN

回答 3

Stack Overflow用户

发布于 2017-02-22 01:12:56

我刚刚将您的代码复制并粘贴到一个游乐场中,我得到的唯一错误是它在guard语句中分配value之前缺少一个let

你确定分段错误是因为这个扩展吗?

这是适用于我的代码(Xcode 8.2.1,Swift 3.0.2):

代码语言:javascript
复制
extension RawRepresentable {

    init?(rawValue optionalRawValue: RawValue?) {

        guard let rawValue = optionalRawValue, let value = Self(rawValue: rawValue) else { return nil }

        self = value
    }
}

编辑-- --

在使用原始值定义enum之后,我确实得到了一个错误。

添加此选项会使游乐场崩溃:

代码语言:javascript
复制
enum Counter: Int {
    case one = 1, two, three, four, five
}

通过将init?中的参数重命名为init?(optRawValue optionalRawValue: RawValue?)修复此问题。我猜问题是你在init?内部调用Self(rawValue: rawValue),而编译器不知道该使用哪一个……

票数 1
EN

Stack Overflow用户

发布于 2017-02-22 04:52:44

不管编译这段代码有什么问题,或者让它按您希望的方式工作,我认为您试图以错误的方式解决底层问题。

尝试设计这样的初始化器是一种反模式: Swift中的Optionals的设计鼓励在最早的机会处理和解决可空性问题,而不是到目前为止难以恢复其起源的级联故障。如果你有一个函数/初始化器,当且仅当它被传递为nil时才返回nil,那么它一开始就不应该接受nil,也永远不会返回nil。

在Swift 3中,您可以保留枚举的默认rawValue初始化器,并通过两种不同的方式之一来解决原始NatashaTheRobot帖子中的问题。

  1. 使用复合if (或guard)语句。

覆盖func prepare(对于segue: UIStoryboardSegue,sender: Any?) { guard let string = segue.identifier,let identifier = SegueIdentifier(rawValue: string) else { return /*或fatalError或任何用于捕获问题的东西*/ }开关标识符{ //处理此处的所有枚举用例}}

  • 使用flatMap (两次)执行函数样式,该函数仅当其输入不为nil时执行闭包:

segue.identifier.flatMap(SegueIdentifier.init).flatMap {开关标识符中的标识符{ //处理所有情况} }

无论采用哪种方式,都是在switch之前展开两个级别的可选性(段是否具有标识符,以及该字符串是否为SegueIdentifier枚举的有效原始值),这意味着switch必须处理所有有效的SegueIdentifier情况。反过来,这意味着如果您后来添加了一个新的SegueIdentifier用例而不处理它,您就会陷入困境。(与switching相反,ing可能是有效的SegueIdentifier或可能为空,这意味着您需要一个default用例,这意味着如果有新的SegueIdentifier需要处理,您将静默失败。)

票数 1
EN

Stack Overflow用户

发布于 2018-06-19 02:18:11

我必须将public添加到init,它编译并通过测试

Apple Swift版本4.1.2 (swiftlang-902.0.54 clang-902.0.39.2)目标: x86_64-apple-darwin17.6.0

代码语言:javascript
复制
extension RawRepresentable {

    public init?(rawValue optionalRawValue: RawValue?) {

      guard let rawValue = optionalRawValue, let value = Self(rawValue: rawValue) else { return nil }

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

https://stackoverflow.com/questions/42373485

复制
相关文章

相似问题

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