Swift中带泛型的递归枚举

Swift中带泛型的递归枚举,swift,recursion,enums,Swift,Recursion,Enums,我是斯威夫特的新手。我试图实现一个具有递归枚举和泛型的二叉树: enum BinaryTree<T> { indirect case Node(T, BinaryTree<T>, BinaryTree<T>) case Nothing } func inorder<T>(_ root: BinaryTree<T>) -> [T] { switch root { case .Nothing: retur

我是斯威夫特的新手。我试图实现一个具有递归枚举和泛型的二叉树:

enum BinaryTree<T> {
  indirect case Node(T, BinaryTree<T>, BinaryTree<T>)
  case Nothing
}

func inorder<T>(_ root: BinaryTree<T>) -> [T] {
  switch root  {
  case .Nothing: 
    return []
  case let .Node(val, left, right):
    return inorder(left) + [val] + inorder(right) 
  }
}
enum二进制树{
间接案例节点(T,BinaryTree,BinaryTree)
没什么
}
func顺序(uuroot:BinaryTree)->[T]{
开关根{
案例。无:
返回[]
案例let.节点(val、左、右):
按顺序返回(左)+[val]+按顺序返回(右)
}
}
以下是我得到的错误:

$ swift ADT.swift 
ADT.swift:83:20: error: cannot convert value of type 'BinaryTree<T>' to expected argument type 'BinaryTree<_>'
    return inorder(left) + [val] + inorder(right) 
                   ^~~~
$swift ADT.swift
ADT.swift:83:20:错误:无法将“BinaryTree”类型的值转换为预期的参数类型“BinaryTree”
按顺序返回(左)+[val]+按顺序返回(右)
^~~~
然而,这是可行的:

func inorder<T>(_ root: BinaryTree<T>) -> [T] {
  switch root  {
  case .Nothing: 
    return []
  case let .Node(val, left, right):
    let l = inorder(left) 
    let r = inorder(right)
    return l + [val] + r
  }
}
func顺序(uuroot:BinaryTree)->[T]{
开关根{
案例。无:
返回[]
案例let.节点(val、左、右):
设l=inorder(左)
设r=inorder(右)
返回l+[val]+r
}
}
我的语法有错误吗?谢谢


我正在使用Swift 3.0。

更新
因此,我试图将这个问题浓缩成最少的示例代码,这些代码无法编译,无法提交。结果证明,这确实是编译器中的一个bug

原始答案
据我所知,你的语法完全正确。Swift编译器的类型推断似乎需要朝着第二个解决方案显然提供的正确方向推进。由于我在过去遇到过几个类似的问题,特别是关于
+
操作符的问题,您的问题启发我尝试其他几种方法加入阵列。这些都是有效的(我只是展示了最后三种情况下的返回语句和支持函数):


如果对Swift编译器有更深入了解的人能够对此有所了解,那就太好了。

谢谢您的解释。有趣的是,有些解决方案甚至在编译时没有提供比原始解决方案更多的关于类型的信息。@Kuan Ying Chou:好吧,所有解决方案的共同点是,编译器不必为(中缀)
+
运算符的链接用法推断所有类型。但编译器未能编译,这被确认为bug。我已经相应地更新了我的答案。
return (inorder(left) as [T]) + [val] + inorder(right)
return Array([inorder(left), [val], inorder(right)].joined())
return [inorder(left), [val], inorder(right)].reduce([], +)
return [inorder(left), [val], inorder(right)].flatMap { $0 }

func myjoin1<T>(_ arrays: [T]...) -> [T]
{
    return arrays.reduce([], +)
}
return myjoin1(inorder(left), [val], inorder(right))

func myjoin2<T>(_ array1: [T], _ array2: [T], _ array3: [T]) -> [T]
{
    return array1 + array2 + array3
}
return myjoin2(inorder(left), [val], inorder(right))

extension Array
{
    func appending(_ array: [Element]) -> [Element]
    {
        return self + array
    }
}
return inorder(left).appending([val]).appending(inorder(right))
return (+)(inorder(left), [val]) + inorder(right)