【问题标题】:Reflection in SwiftSwift 中的反射
【发布时间】:2020-04-16 21:53:34
【问题描述】:

我想创建一个函数 (Function A),它有一个具有多个参数的函数 (Function B) 作为参数。

所以函数(B)可以有0,1个或更多参数,并且在函数(A)内部我想根据B函数参数的数量和类型做不同的事情......

我认为这可以通过反射来实现,但在 Swift 中可以实现吗?

编辑:1 让我们考虑一下我想要支持的函数 B 的三种情况:

func functionB() {
    print(“HelloWorld”) 
}


func functionB(a: Int) {
     print(“HelloWorld1”)
}

func functionB(a: Int, b:String) -> Int {
     print(“HelloWorld2”)
     return 2
}

我希望它独立于函数 B 的签名方法,在函数 A 中执行不同的任务,函数 B 作为参数。

func functionA(function: I don’t know how to pass the different cases of the function B as a parameter...generic types?) {
       if function.args = 0 {
            print(“First example”)
       }
      if function.firstParameter.self is Int.Type {
            print(“second Example”)
      }
      etc...

我想实现这一点,以便用相同的功能处理不同的签名方法。

编辑 2: 很抱歉之前没有指定它,但我无权访问函数 B。我必须弄清楚运行时而不是构建时间。这两个函数在一个单独的包中。 目标是应用程序必须在运行时动态执行不同的任务,只知道方法的签名,特别是参数类型。

【问题讨论】:

  • Swift 内部已经有大量此类内容的元数据,但实际上并没有使用它的反射 API。有第三方反射库可以做到这一点,您可以查看。但是,这种设置似乎很可疑,我怀疑可能有更好的方法来解决这个问题。你到底想达到什么目的?
  • 你能提供一个这样的函数B的例子吗?在 Swift 中,一个函数在一般情况下只能有固定数量的参数。
  • 我将编辑问题以便回复您的 cmets。
  • 向我们展示您如何在运行时获得functionB
  • 这是一个问题。我知道在其他语言中,我可以将一个可以具有 0,1 或 2 个参数的函数 (B) 传递给一个接受所有参数的单个函数 (A)。可以快速实现吗?

标签: swift methods reflection


【解决方案1】:

过载。

func functionA(functionB: () -> Void) { functionB() }
func functionA(functionB: (Int) -> Void) { functionB(0) }
func functionA(functionB: (Int, String) -> Int) { functionB(0, "") }

functionA(functionB: functionB as () -> Void)
functionA( functionB: functionB(a:) )
functionA( functionB: functionB(a:b:) )

【讨论】:

    【解决方案2】:

    根据评论中的建议,您可以使用Any

    func functionA(f: Any, a: Int?, b: String?) {
        if let f = f as? () -> Void {
            f()
        } else if let f = f as? (Int) -> Void , let a = a {
            f(a)
        } else if let f = f as? (Int, String) -> Int, let a = a, let b = b {
            let result = f(a, b)
            print(result)
        } else {
            print("f is not a valid object")
        }
    }
    
    func functionB(a: Int, b: String) -> Int {
        print(a, b)
        return 3
    }
    
    functionA(f: functionB, a: 42, b: "Hello world")
    

    【讨论】:

    • 很抱歉之前没有指定,但我无权访问functionB。我必须在运行时而不是构建时弄清楚。
    • 甚至不需要像这样在类中包装函数,您可以接受 Any 并像 as? (Int, String) -> Int 一样进行转换
    猜你喜欢
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2014-12-02
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多