Swift 带有可变参数的模糊方法

Swift ambiguous methods with variadic parameter

我有以下方法

static func t(key: String, params: AnyObject...) -> String{
    let string = .......
    if (params.count == 0){
        return string
    } else {
        return String(format: string, params)
    }
}

问题是我需要在 Objective C 中提供此方法,这对于可变参数是不可能的。我试图做的是为 objective c 创建另一个方法,其中 params 是一个数组。但是当没有参数时,我还需要第三个。

@objc static func t(key: String, params: [AnyObject]) -> String
@objc static func t(key: String) -> String

但现在 swift 抱怨方法 t 不明确,因为第一种和第三种方法只能使用密钥。

如何进行这项工作?我知道我可以使用不同的名称,但我希望保持一致。

更新: 另一个问题是我无法在函数内部正确调用 String(format:...) ,因为 params 是一个数组而不是一组参数。有什么好的方法可以解决这个问题吗?

您可以执行以下操作:

@objc(C)
public class C : NSObject {

    public static func t(key: String, params firstParam: AnyObject, _ params: AnyObject...) -> String {
        return t(key, params: [firstParam] + params)
    }

    @objc
    public static func t(key: String, params: [AnyObject]) -> String {
        return "TODO"
    }

    @objc
    static func t(key: String) -> String {
        return t(key, params: [])
    }
}

... 从 Swift:

调用
C.t("")
C.t("", params: 1)
C.t("", params: 1, 2)
C.t("", params: [1, 2, 3])

桥接如下:

SWIFT_CLASS_NAMED("C")
@interface C : NSObject
+ (NSString * _Nonnull)t:(NSString * _Nonnull)key params:(NSArray * _Nonnull)params;
+ (NSString * _Nonnull)t:(NSString * _Nonnull)key;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

并可留言如下:

#import "DarkSide.h"
#import "ObjCInterOp-Swift.h"

@implementation DarkSide

- (instancetype)init
{
    self = [super init];
    if (self) {
        [C t:@"" params:@[]];
        [C t:@""];
    }
    return self;
}
@end

关于问题 的更新,有一个格式化的 String 初始化程序版本采用 [CVarArgType] 而不是 CVarArgType...

func f(format format: String, _ params: [CVarArgType]) -> String {
    return String(format: format, arguments: params)
}

f(format: "%d %d %d", [1, 2, 3]) // "1 2 3"

只有CVarArgType不能在Objective C中表示,这确实使事情变得复杂。事实上,如果你真的必须使用 String.init(format: String, arguments: [CVarArgType]) 从 Objective C 得到它,那么我现在不知道如何避免从 [=21 进行转换=]s 到 CVarArgTypes 沿着以下模糊代码行:

@objc(C)
public class C : NSObject {

    public static func t(key: String, params: CVarArgType...) -> String {
        return t(key, params: params)
    }

    public static func t(key: String, params: [CVarArgType]) -> String {
        return String(format: key, arguments: params)
    }

    @objc(t:params:)
    public static func t_objc(key: String, params: [AnyObject]) -> String {
        let args = params.map{
            // here you'll probably need to parse `key` so as to 
            // know what to cast into!
            ([=15=] as! NSNumber).integerValue as CVarArgType
        }
        return t(key, params: args)
    }

    @objc(t:)
    static func t_objc(key: String) -> String {
        return t(key)
    }
}

我的建议是要么放弃 String.init(format: String, arguments: [CVarArgType]) 之类的东西,要么在 Objective C...

中实现基本方法