2016-07-06 18 views
11

Bir fonksiyonun başlığında bir haritadaki tuşun desen eşlemesinin bir yolunu bulmak mümkün görünmüyor. Bunu yapmanın bir yolu var mı? Ne yapmaya çalışıyorum belli anahtar zaten bir harita var olup olmadığını bağlı olarak farklı kod çalıştırılır (ve ayrıca önlemek istedik/else ve benzeri varsa)Elixir'de işlev kafaları içindeki harita tuşlarında desen eşleştirmesi nasıl yapılır

Bu benim kod

neye benzediği bana bu hata veriyor
def my_func(key, %{key => _} = map), do: ... 

** (CompileError) harita anahtarı maçın içinde değişken anahtarın yasadışı kullanımı, haritalar sadece^kullanarak değişkeni mevcut üzerine eşleşebilir

anahtar

Tabii

Ben de o zaman

** (CompileError) verir ^

def my_func(key, %{^key => _} = map), do: ... 

ilişkisiz değişken^anahtar

kullanıyorum iksir kullanarak denedim 1.3.1/erlang 19.0 x64 bir Windows 8.1 makinede. Okumak için teşekkürler! İhtiyacınız anahtarla

cevap

12

Hemen desen maç: IEX içinde Sonra

defmodule Test do 
    def my_func(%{"a" => value}), do: {:a, value} 
    def my_func(%{"b" => value}), do: {:b, value} 
    def my_func(_), do: :error 
end 

: maddelerinin

Ayrıca
iex(1)> Test.my_func(%{"a" => 1}) 
{:a, 1} 
iex(2)> Test.my_func(%{"b" => 2}) 
{:b, 2} 

sırası önemlidir. Örneğin %{"b" => 2} maç için çalışıyoruz ama ilk fıkrada olduğu için, haritanın %{"a" => 1, "b" => 2} aşağıdaki anahtar "a" ilk maç olacak varsa: Her anahtar için bir şeyler oluşturmak istiyorsanız

iex(3)> Test.my_func(%{"a" => 1, "b" => 2}) 
{:a, 1} 

sen eşleşebilir Farklı bir yaklaşım öneririm. O anahtarlarına bir işlev eşlemek istediğiniz Örneğin,:

defmodule Test0 do 
    def my_op({"times_2", value}), do: {"times_2", value * 2} 
    def my_op({"times_3", value}), do: {"times_3", value * 3} 
    def my_op({key, value}), do: {key, value} 

    def my_func(m) do 
    Enum.map(m, &my_op/1) |> Enum.into(%{}) 
    end 
end 

Yani şu alacağı: Bu yanıt için yorumlarına göre

iex(1)> Test0.my_func(%{"times_2" => 2, "times_3" => 3, "whatever" => 42}) 
%{"times_2" => 4, "times_3" => 9, "whatever" => 42} 

Güncelleme

Sen desen bir değişkenin anahtarıyla eşleşemez. Sorun, derleyicinin henüz bilmediği bir şeyi aramak için kod oluşturması gerektiğidir. Eşleştirmeyi yaptığınızda genellikle derleyiciye ne alacağının bazı ipuçlarını verirsiniz. Haritalardaki tuşlar için ipucu anahtardır. Bu durumda, ilk argümanın aramanın anahtarı olması gerektiğini işaret etse bile, derleyici için yeterli değildir. Bu nedenle, yaklaşımınız bir if ifadesi kullanmak olmalıdır: Bu, sorunuzu yanıtlıyordur.

+0

Merhaba, cevabınız için teşekkürler.Ama muhtemelen 'my_func (key, _) 'deki anahtarın çalışma zamanında belirlenen bir değişken olduğunu açıklığa kavuşturmalıyım. – bottlenecked

+0

derleme zamanında bilinmemekte, şimdi ne yapmaya çalıştığınızı kısmen anlıyorum. Tam olarak fonksiyonun ne yapar? –

+0

Um, bu fonksiyon gövdesini eklemek için ilgili olduğunu düşünüyorum yoktu, ama son kod kabaca yapacak "anahtar zaten bir uyarı tetikleyecek varsa, başka foo yapmak ve haritaya eklemek" – bottlenecked