如何解决“不允许通用参数”

时间:2015-05-20 17:32:22

标签: generics nim

TL; DR: 如果您遇到类似的问题,请先检查您是否做过一些完全愚蠢的事情,例如将:=混为一谈。我对错误消息感到困惑,我设法通过另一个愚蠢的错误重现了一个愚蠢的错误,所以请大笑:

我遇到了一个问题,我遇到了错误no generic parameters allowed。这个问题可能最好用简化的解释:仅仅通过第一个元素比较元组的问题。考虑这个例子:

import algorithm

# just a dummy type emphasizing that it should not be
# used for the comparison
type
  NotComparable = object

# generic proc to compare a tuple by the first element
proc cmpByKey[K,V](x: (K,V), y: (K,V)): int = 
  system.cmp(x[0], y[0])

# now the actual challenge: how to write a function which
# takes some collection of tuples and defines a local
# key comparator for the given tuple.
proc sortByFirstTupleElement[K,V](data: seq[(K,V)]) =
  let compare = cmpByKey[K,V]
  sort[(K,V)](cmp: compare)

let data = @[(2, NotComparable()),
             (1, NotComparable()),
             (3, NotComparable())]

sortByFirstTupleElement[int, NotComparable](data)

此示例生成Error: no generic parameters allowed for sort。我已经尝试了各种语法变体,也定义了比较器proc嵌套。我不明白:为什么比较器仍然被认为是通用的?我期望在sortByFirstTupleElement KVint类型是来自调用上下文的实例化类型,即NotComparablecmpByKey[K,V]。因此,我希望cmpByKey[int,NotComparable]成为具体的photos。是否存在使比较器具体化的语法技巧?

如果无法做到这一点,这里有哪些可行的解决方法?也许不只是在这个例子中,但一般情况下?我想每次泛型proc必须传递另一个涉及泛型类型的proc时会出现这个问题吗?

1 个答案:

答案 0 :(得分:4)

您的问题是您使用错误的参数调用sort。您没有通过data参数进行排序,data不是var参数,因此它不可变。此外,cmp不是命名参数,因此只需直接传递比较函数即可。 E.g:

import algorithm

# just a dummy type emphasizing that it should not be
# used for the comparison
type
  NotComparable = object

# generic proc to compare a tuple by the first element
proc cmpByKey[K,V](x: (K,V), y: (K,V)): int = 
  system.cmp(x[0], y[0])

# now the actual challenge: how to write a function which
# takes some collection of tuples and defines a local
# key comparator for the given tuple.
proc sortByFirstTupleElement[K,V](data: var seq[(K,V)]) =
  let compare = cmpByKey[K,V]
  data.sort(compare)

var data = @[(2, NotComparable()),
             (1, NotComparable()),
             (3, NotComparable())]

sortByFirstTupleElement(data)

此外,let compare = ...是多余的。您可以直接致电data.sort(cmpByKey[K,V])

您收到错误消息是因为您使用了对象构造函数语法(cmp: compare)而不是命名参数语法(cmp = compare),这使得Nim查找名为{的对象类型{1}}而不是名为sort的过程。错误信息仍然有点令人困惑,但它来自哪里。