将 Swift 变量名转换为字符串,用作字符串?

Convert Swift variable name to string, to use as string?

我有一个要导入的纹理,其名称与表示其状态的变量布尔值相同。

let myButtonNameABC = false

有没有办法将这个变量的名称转换为字符串,以便它可以用来加载同名的图像?

你可以把它变成一个函数而不是一个变量,并做同样的事情。我会分步骤解释。

那么首先,我们如何使函数与变量相同?

基本上,我们将变量“包装”在函数内部。这类似于我在您最新的 RefBool 线程中建议的第一个块的方法,我们通过函数获取或设置一个值。

在这里,我们使用 methods/functions 直接更改变量而不带参数——因此,我们将按名称使用该函数,而不是在我们的代码中按名称使用变量来访问它:

enum Static {
  private static var _button1 = false
  static func button1() { toggle(&_button1) }
}

注意,Enum 只是我们调用方法的命名空间,以强调我们的代码工作不需要变量名--只有函数需要知道它的 name.This 代码也可以在结构或 class 内部工作,甚至可以在全局命名空间中工作。

所以这里,如果我想改变_button1的值,我必须调用button1() _button1本质上是不可见的每个人和每件事——没关系,因为我们只需要 button1() 来完成我们的工作。

所以现在,每次我们调用 Static.button1() 时,Static._button1 都会将 true 切换为 falsefalse 切换为 true,并且等等(使用我之前给你的功能)


我们为什么要这样做?

嗯,因为没有 Mirror 和反射就无法获取变量的名称,并且已经有一个名为 #function 的内置命令。我们正在跳过使用该函数的附加环节,因此我们不必设置镜像和其他 OBJc 环节。

让我们修改 enum 来演示如何获取 func 的名称:

 enum Static {
  private static var _button1 = false
  
  static func button1() -> String { 
    toggle ( &_button1 ) 
    return ( #function )
  }
}

现在,当我们调用 button1() 时,我们做了两件事:1,我们切换按钮 (_button1) 的状态,我们 return 一个名为“button1()”的字符串“

let buttonName = Static.button1()  // buttonName = "button1()"

我们可以通过调用 String 的成员来改变自身来使其更有用:

let trimmedButtonName = Static.button1().replacingOccurrences(of: "()", with: "")
// trimmedButtonName = "button1"

让我们现在用这个方便的替代品来更新我们的 enum

enum Static {
  private static var _button1 = false
  
  static func button1() -> String { 
    toggle ( &_button1 ) 
    return ( #function.replacingOccurrences(of: "()", with: "") )
  }
}

而我们的最终用例如下:

let buttonName = Static.button1()

注:

您不必将 _button1 设为私有,这只是为了证明您 不需要 将其设为 public。如果你需要获取它的状态,你可以创建另一个函数,或者 return 来自 button1():

的元组类型
static func button1() -> (name: String, state: Bool) {
// ...        
  return ( #function.etc, _button1)
}

let results = Static.button1()
print( results.name  ) // "button1"
print( results.state ) //  true / false

如果您需要更明确地控制变量的设置,您也可以在参数中设置一些内容,就像任何普通函数一样。


更新:

例如,如果你想使用显式控制,你可以这样做:

func button1(equals: Bool? = nil) -> (name: String, state: Bool) {
  if equals != nil {
    // do the code mentioned above
  } else {
    _button1 = equals!
  }

  return (#function.replacingOccurrences(of: "()", with: ""), _button1)
}

let buttonState.state = Static.button1(equals: false) // false
let buttonStateAgain.state = Static.button1(equals: true) // true
print(Static.button1().name) // "button1"
  

您可以为此使用镜像。

struct Test {
    let myButtonNameABC = false
}

let childrens = Mirror(reflecting: Test()).children

childrens.forEach {
    print([=10=].label ?? "")
}

这将打印:

myButtonNameABC

您可以找到有关镜像的信息 here