Generics 如何解决;不允许使用通用参数";

Generics 如何解决;不允许使用通用参数";,generics,nim-lang,Generics,Nim Lang,TL;DR:如果你有类似的问题,首先检查你是否做过一些完全愚蠢的事情,比如把:和=混淆。我被错误信息弄得不知所措,我设法用另一个愚蠢的错误重现了一个愚蠢的错误,所以请大家开怀大笑: 我遇到了一个问题,当时我正在努力处理错误不允许使用通用参数。这个问题最好用简化的from来解释:仅通过元组的第一个元素来比较元组的问题。考虑这个例子: import algorithm # just a dummy type emphasizing that it should not be # used for

TL;DR:如果你有类似的问题,首先检查你是否做过一些完全愚蠢的事情,比如把
=
混淆。我被错误信息弄得不知所措,我设法用另一个愚蠢的错误重现了一个愚蠢的错误,所以请大家开怀大笑:

我遇到了一个问题,当时我正在努力处理错误
不允许使用通用参数
。这个问题最好用简化的from来解释:仅通过元组的第一个元素来比较元组的问题。考虑这个例子:

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)
此示例生成
错误:排序不允许使用通用参数。我尝试了各种语法变体,还定义了comparatorproc嵌套。我不明白的是:为什么比较器仍然被认为是通用的?我希望在
sortbyFirstPleeElement
中,类型
K
V
是调用上下文中的实例化类型,即
int
NotComparable
。因此,我希望
cmpByKey[K,V]
是具体的
cmpByKey[int,NotComparable]
。是否有一种句法技巧可以使比较器具体化


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

您的问题是调用
排序时使用了错误的参数。您不需要传递
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
的过程。错误消息仍然有点混乱,但这就是它的来源。

您的问题是调用的
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
的过程。错误消息仍然有点混乱,但这就是它的来源。

哦,多么愚蠢的错误。。。这个错误信息让我一直担心完全错误的事情。我原来的问题也是这样。在那里,以下令人惊讶的行为进一步混淆了这个问题:出于某种原因,如果comparator参数的默认值为
system.cmp
,则忽略传入函数(尽管不能简单地复制)。也许这就是为什么
sort
一开始没有
cmp
的默认值的原因吧?我已经更新了帖子,解释了错误消息令人困惑的原因。哦,多么愚蠢的错误。。。这个错误信息让我一直担心完全错误的事情。我原来的问题也是这样。在那里,以下令人惊讶的行为进一步混淆了这个问题:出于某种原因,如果comparator参数的默认值为
system.cmp
,则忽略传入函数(尽管不能简单地复制)。也许这就是为什么
sort
一开始没有
cmp
的默认值的原因吧?我已经更新了帖子,解释了导致错误消息混乱的原因。