1

TL;DR: 如果您有类似的问题,请首先检查您是否做过一些完全愚蠢的事情,例如将 a:与 a混淆=。我对错误消息感到非常困惑,以至于我设法用另一个愚蠢的错误重现了一个愚蠢的错误,所以笑一笑:

我遇到了一个我正在努力解决错误的问题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. 我尝试了各种语法变体,还定义了嵌套的比较器过程。我不明白的是:为什么比较器仍然被认为是通用的?我期待在sortByFirstTupleElement类型中KV是来自调用上下文的实例化类型,即intNotComparable. 因此,我希望cmpByKey[K,V]是具体的cmpByKey[int,NotComparable]。是否有使比较器具体化的语法技巧?

如果这是不可能的,这里有什么可能的解决方法?也许不仅仅是在这个例子中,而是在一般情况下?我想每次泛型proc必须传递另一个涉及泛型类型的proc时都会出现这个问题?

4

1 回答 1

4

您的问题是您使用sort错误的参数进行调用。您不将data参数传递给排序,并且data不是 var 参数,因此它不是可变的。另外,cmp不是命名参数,所以直接传递比较函数即可。例如:

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 会查找名为的对象类型sort而不是名为的过程sort。错误消息仍然有点令人困惑,但这就是它的来源。

于 2015-05-20T17:49:26.473 回答