> 1 <

Автор Сообщение

dgee519

Members


Статус

4 сообщений

Где: ---
Род занятий:
Возраст:

#5849   2012-03-07 07:53 GMT+3 часа(ов)      
Есть функция f (args), возвращает список значений (value1 value2). Как присвоить переменным var1 var2 значения value1 value2 вызвав функцию один раз?
Пока сделал так, но криво ведь:
 
(let ((result (f args)))
(setf var1 (first result)
var2 (second result)))
 

Заранее признателен.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#5850   2012-03-07 08:23 GMT+3 часа(ов)      
Можно, например, использовать макрос destructuring-bind. Описание здесь.
Пример.
CL-USER> (defun f () (list 1 2))
F
CL-USER> (destructuring-bind (a b) (f) (list b a))
(2 1)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5851   2012-03-07 16:24 GMT+3 часа(ов)      
Цитата
Есть функция f (args), возвращает список значений (value1 value2).
Может лучше не список, а values? Опишите ситуацию подробнее (с кодом).
Цитата
Как присвоить переменным var1 var2 значения value1 value2 вызвав функцию один раз?
Для списка
CG-USER(1): (defun f () (list 1 2))
F
CG-USER(2): (setf (values a b) (values-list (f)))
1
2
CG-USER(3): a
1
CG-USER(4): b
2

Цитата
Пока сделал так, но криво ведь
А почему криво?

LinkFly

Members


Статус

152 сообщений

Где: Russia
Род занятий:
Возраст:

#5852   2012-03-07 17:39 GMT+3 часа(ов)      
> (setf (values a b) (values-list (f)))

Круто! Не знал))

А насчёт:

(let ((result (f args)))

(setf var1 (first result)

var2 (second result)))

... не надо "лохматить бабушку", так - нормально )

LinkFly

Members


Статус

152 сообщений

Где: Russia
Род занятий:
Возраст:

#5853   2012-03-07 17:44 GMT+3 часа(ов)      
А вообще по ситуации, как дальше будут использоваться var1 и var2 ? Может быть они первый раз и используются и должны быть локальные? Тогда их надо добавить в let, следующий этап рефакторинга - если result нигде использоваться не будет (а только для инициализации var1 и var2) тогда имеет смысл от этого result избавиться с помощью того же destructuring-bind.

Ну и действительно, стоит рассмотреть вариант с волшебным (setf (values var1 var2) ...)

dgee519

Members


Статус

4 сообщений

Где: ---
Род занятий:
Возраст:

#5857   2012-03-08 03:14 GMT+3 часа(ов)      
Спасибо, values и values-list - это то, что мне нужно.
Result - это переменная, которая используется только для инициализации var1 и var2. Поэтому мне не нравится мое решение.
Цитата
Может лучше не список, а values?

Я попробую.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#5864   2012-03-08 16:58 GMT+3 часа(ов)      
Цитата
Result - это переменная, которая используется только для инициализации var1 и var2. Поэтому мне не нравится мое решение.
Можно написать макрос наподобие
CG-USER(1): (defmacro set-vars (vars value)
(let ((gvars (mapcar #'(lambda(v) (gensym)) vars)))
`(destructuring-bind ,gvars ,value
,@(mapcar #'(lambda(v gv) `(setq ,v ,gv)) vars gvars))))
SET-VARS
CG-USER(2): (macroexpand '(set-vars (a b c d) '(1 2 3 4)))
(LET* ()
(LET* ((#:G1407 '1) (#:G1408 '2) (#:G1409 '3) (#:G1410 '4))
(SETQ A #:G1407)
(SETQ B #:G1408)
(SETQ C #:G1409)
(SETQ D #:G1410)))
T
CG-USER(3): (macroexpand '(set-vars (a b c d) (test)))
(LET* ()
(LET* ((#:G1417 (TEST))
(#:G1413 (EXCL::CAR-FUSSY #:G1417 '#:G1413))
(#:G1414 (EXCL::CAR-FUSSY # '#:G1414))
(#:G1415 (EXCL::CAR-FUSSY # '#:G1415))
(#:G1416 (EXCL::CAR-FUSSY # '#:G1416))
(#:G1418 (EXCL::LAMBDASCAN-MAXARGS 0 # '#)))
(DECLARE (IGNORABLE #:G1418))
(SETQ A #:G1413)
(SETQ B #:G1414)
(SETQ C #:G1415)
(SETQ D #:G1416)))
T
 
> 1 <


Онлайн :

0 пользователь(ей), 28 гость(ей) :




Реклама на сайте: