2017-12-04 12 views
3

clojure 벡터가 연관 인터페이스를 구현한다는 사실에 놀랐습니다.벡터가 연관성을 구현하는 이유는 무엇입니까?

(associative? [1 2 3]) ; => true 

이 인터페이스는 키에 의한 최적의 색인 생성을 제공한다고 가정합니다. 이 가정에 따르면, 인터페이스는 맵 데이터 구조에는 적합하지만, 마음에 키 - 값 경험적 방법을 따르지 않는 벡터에 대해서는 이상합니다.

내 정신 모델 Associative 또는 vector의 구현이 올바르지 않습니까? 이 디자인 선택의 목적은 무엇입니까?

답변

8

처음에는 직관적으로 보이지 않을 수도 있지만 벡터는 모든 표준 연관 함수를 사용할 수 있도록 색인에 의해 키가 지정됩니다. 이 디자인 선택하지 않고

(def v [[1 2 3] 
     [4 5 6] 
     [7 8 9]]) 

(assoc-in v [2 1] 0) 
[[1 2 3] 
[4 5 6] 
[7 0 9]] 

, 기능의 전체 집합을 별도 될 필요가있다 : 당신은 2D 벡터가있는 경우,

(def v [1 2 3]) 

(assoc v 1 4) 
[1 4 3] 

(update v 1 inc) 
[1 3 3] 

(get v 1) 
2 ; Same as (v 1) 

을 또는이 매우 쉽게 그들에 간단한 작업을 할 수 있습니다 특별히 벡터 용으로 생성되고 사용됩니다. 표준화 된 인터페이스를 사용하면 작업중인 구조를 특별히 신경 쓰지 않는 함수를 작성할 수 있습니다.

이렇게 생각하십시오. 벡터의 요소를 "대체하는"함수를 작성하려고한다고 가정 해보십시오. 그 서명이 기존의 assoc 함수와 다를지라도; 특히 벡터를 기대하는 것 외에?

4

Clojure 벡터는 인덱스에 값을 연결합니다. 이는 다음과 같은 일을 할 수 있음을 의미합니다.

(assoc [0 1] 0 2) 

(reduce-kv (fn [m idx v] 
      (assoc m idx v)) {} [0 1 2]) 

둘 다 효율적입니다.