Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Swift中的函数参数消除对泛型函数的调用的歧义?_Swift_Generics_Ambiguous - Fatal编程技术网

如何使用Swift中的函数参数消除对泛型函数的调用的歧义?

如何使用Swift中的函数参数消除对泛型函数的调用的歧义?,swift,generics,ambiguous,Swift,Generics,Ambiguous,我正在编写一个解析器类,它希望以特定的顺序读取一系列标记。语法中的某些产品具有可选的非终端,因此我想创建一个通用的“maybe”函数,该函数可以作为回调传递给负责解析非终端的函数。通常,函数会在失败时抛出错误,但由于在某些情况下它是可选的,因此maybe函数会抑制错误。然而,Swift提供了一个错误“表达式的类型在没有更多上下文的情况下是不明确的”,我无法找出正确的类型转换和/或键入来消除歧义 以下是我为重新创建错误所能编写的最少代码量: public struct VariableDeclar

我正在编写一个解析器类,它希望以特定的顺序读取一系列标记。语法中的某些产品具有可选的非终端,因此我想创建一个通用的“maybe”函数,该函数可以作为回调传递给负责解析非终端的函数。通常,函数会在失败时抛出错误,但由于在某些情况下它是可选的,因此maybe函数会抑制错误。然而,Swift提供了一个错误“表达式的类型在没有更多上下文的情况下是不明确的”,我无法找出正确的类型转换和/或键入来消除歧义

以下是我为重新创建错误所能编写的最少代码量:

public struct VariableDeclaration {
    public let identifier: Identifier
    public let type: String?
}

public struct Identifier { }

public class Parser {
    
    public func parseVariableDeclaration() throws -> VariableDeclaration {
        let identifier = try self.parseIdentifier()
        let type = self.maybe(self.parseType)
        return VariableDeclaration(identifier: identifier, type: type)
    }
    
    public func parseIdentifier() throws -> Identifier { return Identifier() }
    
    public func parseType() throws -> String { return "" }
    
    public func maybe<T>(_ callback: (Parser) -> () throws -> T) -> T? {
        do {
            return try callback(self)()
        }
        catch {
            return nil
        }
    }
}
公共结构变量声明{
公共let标识符:标识符
公共let类型:String?
}
公共结构标识符{}
公共类解析器{
public func parseVariableDeclaration()抛出->VariableDeclaration{
让标识符=尝试self.parseIdentifier()
让type=self.maybe(self.parseType)
返回变量声明(标识符:标识符,类型:类型)
}
public func parseIdentifier()抛出->标识符{return Identifier()}
public func parseType()抛出->字符串{return”“}
公共函数可能(uu回调:(解析器)->()抛出->T)->T{
做{
返回try回调(self)()
}
抓住{
归零
}
}
}
以下是我在消除问题行歧义方面的一些失败尝试:

let type: String? self.maybe(self.parseType)
let type = self.maybe(self.parseType) as String?
let type = self.maybe<String>(self.parseType)
let类型:字符串?self.maybe(self.parseType)
让type=self.maybe(self.parseType)作为字符串?
让type=self.maybe(self.parseType)

这里的问题不是通用参数。第一次和第二次尝试将告诉编译器
T
应该是什么类型

问题是作为
回调传递的值,该值具有以下签名:

(解析器)->()抛出->T
您正在传入具有以下签名的
self.parseType

()抛出->字符串
使用
Self.parseType
(注意大写的
S
)或
Parser.parseType
作为
回调的值是可行的

或者,您可以这样定义
可能

        let type = self.maybe(Parser.parseType)
public func可能(uCallback:(解析器)抛出->T)->T?{
做{
返回尝试回调(self)
}抓住{
归零
}
}
然后这样称呼它:

        let type = self.maybe(Parser.parseType)
let type=self.maybe{try$0.parseType()}

我不确定这是否真的是你想要做的,但是如果你想保留
的签名,也许
,你需要像这样传递方法的部分引用:

        let type = self.maybe(Parser.parseType)

我无法编译
Self.parseType
(它拒绝将
Self
转换为
Parser
),但
Parser.parseType
工作成功。lambda的建议也起了作用。谢谢您的全面回复。@Jared啊,那是因为
解析器
是一个(非最终)类。因此子类中的
Self
将不是(精确的)
解析器
。。。