我可以使用 swift 使 self.entity 成为组件中某些功能的非可选功能吗?

Can I make self.entity a non optional for certian functions in a GKComponent using swift?

我正在使用 GameplayKit 实体组件系统开发游戏。

我有多个GKComponent。大多数实例函数要求 self.entity 不是 nil,但它是可选的,因为组件可能在附加到实体之前被初始化。

如果我 "do things properly",我知道我应该使用 guard(或 if)来检查 self.entity 是否为零,对于我需要它的每个函数。这为每个功能添加了一大块额外代码,此外,功能可能需要实体具有特定组件才能运行。

问题陈述:

对于 GKComponent 中的一些函数,我想指定该函数需要 self.entity 不是 nil,并且有一些特定的组件,而不需要一些 guard 或 if 语句来增加我的代码。

我尝试过的事情:

我尝试创建 GKComponent 的扩展。 该扩展包含一个函数,如果实体为 nil 则抛出错误,return如果它不是 nil 则为真。

import Foundation
import GameplayKit

extension GKComponent {

  enum ComponentExtensionError: Error {
    case hasNoEntity
  }

  func requiresEntity() throws -> Bool {
    if (self.entity != nil) {
      return true
    } else {
      throw ComponentExtensionError.hasNoEntity
    }
  }

}

GK组件函数:

func setTileWalls () {
    try? self.requiresEntity()
    # Some stuff
}

这可以编译,但没有解决我的问题,因为我仍然必须以 self.entity?.somefunc() 的身份访问实体。 我想现在我知道 self.entity 不是零,我可以继续将它设置为展开...

func setTileWalls () {
    try? self.requiresEntity()
    self.entity = self.entity!
    # Some stuff
}

但是,唉,你不能设置self.entity。

我认为我可以改为将扩展修改为 return 实体,然后执行类似...

func stTileWalls () {
    guard let entity = self.requiresEntity() else { throw }
}

但随后我需要修改每个函数代码以使用 entity 而不是 self.entity。我觉得这不是最佳解决方案,但也许是可以接受的。

我理想的解决方案是能够调用一个函数来检查 self 是否有一个实体和一些组件,使它们对于范围来说是非可选的,如果有任何是 nil 则抛出错误。

为什么?我对实体和任何组件总是可选的感到沮丧(当我知道它不应该时)。如果我理解正确的话,"doing things properly" 要求我守卫和投掷(或者 return 可能?)。从语法上讲,我觉得它看起来很丑陋,而且我觉得在使用 Swift.

以优雅的方式修复它方面我遗漏了一些东西

如果您想要一个安全的解决方案,需要比展开可选代码更少的样板代码,则没有简单的解决方案来解决这个问题。 抛出错误而不是返回 nil 绝对是个坏主意,因为处理错误需要的样板代码比安全地解包可选代码还要多。

您不能覆盖现有的变量类型,因此您也不能使 GKComponent.entity 成为非可选的。

使用 guard 语句进行可选绑定,这样您就可以最小化解包值的样板代码。