2015-05-20 3 views
1

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. Я пробовал всевозможные синтаксические вариации, также определяя, что компаратор-процесс вложен. Что я не понимаю: почему компаратор по-прежнему считается общим? Я ожидал, что в пределах sortByFirstTupleElement типы K и V являются экземплярами типов из контекста вызова, то есть int и NotComparable. Поэтому я ожидал, что cmpByKey[K,V] будет конкретным cmpByKey[int,NotComparable]. Есть ли синтаксический трюк, чтобы сделать компаратора конкретным?

Если это невозможно, какие возможные обходные пути здесь? Может быть, не только конкретно в этом примере, но и вообще? Я предполагаю, что эта проблема возникает каждый раз, когда общий proc должен передать другой процесс, который включает общий тип?

ответ

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. Сообщение об ошибке все еще немного запутанно, но это то, откуда оно исходит.

+0

О, какая глупая ошибка ... Это сообщение об ошибке заставило меня беспокоиться о совершенно неправильной вещи все время. Точно так же в моей первоначальной проблеме. Там проблема была еще более запутана следующим удивительным поведением: по какой-то причине, если аргумент компаратора имеет значение по умолчанию 'system.cmp', моя переданная функция игнорируется (не может воспроизводиться тривиально, хотя). Может быть, это причина, почему 'sort' не имеет значения по умолчанию для' cmp' в первую очередь? – bluenote10

+0

Я обновил сообщение, чтобы объяснить причину непонятного сообщения об ошибке. –

Смежные вопросы