2013-05-24 3 views
0

Можно ли это сделать в одной функции:Возможно ли разрушить карту в привязке?

(binding [*configs* (merge default-configs configs)] 
    (let [{:keys [login url max-pages]} *configs*] 
     .. 

Когда я попытался это:

(binding [{:keys [login url max-pages] :as *configs*} (merge default-configs configs)] 

Он дал мне эту ошибку:

CompilerException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.Symbol

Немного прибегая к помощи мне показал, что Common Lisp имеет функцию destructure-bind, но я не уверен, что это связано.

ответ

2

Нет, ничего подобного не будет работать с основными макросами.

Причина в том, что оба binding и let (и друзья, например with-bindings) делают только одно. В случае с binding эта штука устанавливает поточно-локальные привязки для Vars; для let, он вводит локальные привязки. Это совершенно разные операции.

В let деструктурирование имеет четкое значение: оно вводит новые местные жители, что и делает базовые, неразрушающие привязки let. Это также очевидно полезно, поскольку общими потребностями являются привлекательные структуры данных приложения и привязка разных частей к различным местным жителям. Имена местных жителей также определяются локально, поэтому такие вещи, как :keys в ассоциативной деструкции, хорошо работают.

В binding, чтобы соответствовать его основной цели, деструктурирование потребовало бы привязки нескольких варов одновременно к нескольким частям структуры данных. Это не так полезно. Если вместо этого деструктурировать в binding было введение местных жителей, то внезапно binding выполнил бы две несвязанные вещи, возможно, как в одной и той же паре привязки (обратите внимание на то, как форма отказа binding из текста вопроса ожидает, что привязки, введенные , являются локальными, но привязка, сделанная :as, является обычным связыванием по нити в Var). Таким образом, binding просто предпочитает не поддерживать деструктурирование. (Если вам нужно связать части структуры данных для несколько Варса, вы можете использовать let для выполнения деструктурирующего, а затем установить вязки с binding.)


Что касается destructuring-bind, это в основном деструктурирующей поддержки версия let в Common Lisp. CL let не поддерживает деструктурирование.

+0

Это имеет смысл, я никогда не думал о том, будут ли эти: ключи «локальными или динамическими»? –

1

"Binding формы (DESTRUCTURING)" section:

Clojure supports abstract structural binding, often called destructuring, in let binding lists, fn parameter lists, and any macro that expands into a let or fn. ...

AFAIK binding сам по себе не использует механизм DESTRUCTURING (через fn из let).

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

  • Нет связанных вопросов^_^