在不同模块中定义泛型时无法推断通用参数

时间:2016-12-09 17:01:11

标签: swift generics

我有一个swift存储库,它定义了2个模块:

Sources/Parser/Parser.swift包含:

public struct Parser<Token, Output> {
  public let parse: (AnyCollection<Token>) throws -> (Output, AnyCollection<Token>)
}

public func countingParser() -> Parser<Character,Int> {
  return Parser { input in
    return ( 1, input.dropFirst( 1 ) )
  }
}

Sources/External/Parser.swift包含:

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  return Parser { input in
    return ( 1, input.dropFirst( 1 ) )
  }
}

为了完整起见,我的Package.swift包含:

import PackageDescription

let package = Package(
    name: "SwiftBug",
    targets: [ Target( name: "External", dependencies: [ "Parser" ] ) ]
)

尽管countingParserexternalCountingParser基本上是相同的代码,但我在External/Parser.swift使用swift 3.0.1时出现编译错误。

Sources/External/Parser.swift:4:10: error: generic parameter 'Token' could not be inferred
  return Parser { input in
         ^
Parser.Parser:1:15: note: 'Token' declared as parameter to type 'Parser'
public struct Parser<Token, Output> {
              ^
Sources/External/Parser.swift:4:10: note: explicitly specify the generic arguments to fix this issue
  return Parser { input in
         ^
               <Any, Any>

无论我做什么来进一步指定函数内部Parser的类型,我都无法编译它。为什么在定义Parser的模块中定义时工作正常,但在同一模块外定义时无法编译?

编辑:如果按照以下建议进行@ PEEJWEEJ编辑,仍然存在编译错误,但错误消息已更改:

Sources/External/Parser.swift

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  let p: Parser<Character, Int> = Parser<Character,Int>( parse: { input in
    return ( 1, input.dropFirst(1) )
  } )

  return p
}

现在产生错误:

Sources/External/Parser.swift:4:35: error: expression type 'Parser<Character, Int>' is ambiguous without more context
  let p: Parser<Character, Int> = Parser<Character,Int>( parse: { input in
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sources/External/Parser.swift中指定了更多类型信息:

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  let p: Parser<Character, Int> = Parser<Character,Int> { (input: AnyCollection<Character>) -> (Int,AnyCollection<Character>) in
    return ( 1, input.dropFirst(1) )
  }

  return p
}

以下诊断结果:

Sources/External/Parser.swift:4:96: error: declared closure result '(Int, AnyCollection<Character>)' is incompatible with contextual type '(_, AnyCollection<_>)'
  let p: Parser<Character, Int> = Parser<Character,Int> { (input: AnyCollection<Character>) -> (Int,AnyCollection<Character>) in
                                                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                                               (_, AnyCollection<_>)

1 个答案:

答案 0 :(得分:0)

问题似乎是Parser的默认构造函数默认为内部。将此问题归结为另一条错误的诊断信息。

如果我将struct Parser的声明更改为:

public struct Parser<Token, Output> {
  public typealias ParseFunction = (AnyCollection<Token>) throws -> (Output, AnyCollection<Token>)
  public let parse: ParseFunction
  public init( parse: @escaping ParseFunction ) {
    self.parse = parse
  }
}

然后我们编译得很好。