Elixir Language
Согласование образцов
Поиск…
Функции сопоставления шаблонов
#You can use pattern matching to run different
#functions based on which parameters you pass
#This example uses pattern matching to start,
#run, and end a recursive function
defmodule Counter do
def count_to do
count_to(100, 0) #No argument, init with 100
end
def count_to(counter) do
count_to(counter, 0) #Initialize the recursive function
end
def count_to(counter, value) when value == counter do
#This guard clause allows me to check my arguments against
#expressions. This ends the recursion when the value matches
#the number I am counting to.
:ok
end
def count_to(counter, value) do
#Actually do the counting
IO.puts value
count_to(counter, value + 1)
end
end
Согласование шаблонов на карте
%{username: username} = %{username: "John Doe", id: 1} # username == "John Doe"
%{username: username, id: 2} = %{username: "John Doe", id: 1} ** (MatchError) no match of right hand side value: %{id: 1, username: "John Doe"}
Сопоставление шаблонов в списке
Вы также можете сопоставлять шаблоны в Elixir Data Structures, таких как списки.
Списки
Совпадение по списку довольно простое.
[head | tail] = [1,2,3,4,5] # head == 1 # tail == [2,3,4,5]
Это работает, сопоставляя первые (или более) элементы в списке с левой стороны |
(труба), а остальная часть списка - с правой стороны переменной |
,
Мы также можем сопоставлять определенные значения списка:
[1,2 | tail] = [1,2,3,4,5] # tail = [3,4,5] [4 | tail] = [1,2,3,4,5] ** (MatchError) no match of right hand side value: [1, 2, 3, 4, 5]
Связывание нескольких последовательных значений слева от |
также разрешено:
[a, b | tail] = [1,2,3,4,5]
# a == 1
# b == 2
# tail = [3,4,5]
Еще сложнее - мы можем сопоставлять определенное значение и сопоставлять его с переменной:
iex(11)> [a = 1 | tail] = [1,2,3,4,5] # a == 1
Получите сумму списка с использованием соответствия шаблону
defmodule Math do
# We start of by passing the sum/1 function a list of numbers.
def sum(numbers) do
do_sum(numbers, 0)
end
# Recurse over the list when it contains at least one element.
# We break the list up into two parts:
# head: the first element of the list
# tail: a list of all elements except the head
# Every time this function is executed it makes the list of numbers
# one element smaller until it is empty.
defp do_sum([head|tail], acc) do
do_sum(tail, head + acc)
end
# When we have reached the end of the list, return the accumulated sum
defp do_sum([], acc), do: acc
end
Анонимные функции
f = fn
{:a, :b} -> IO.puts "Tuple {:a, :b}"
[] -> IO.puts "Empty list"
end
f.({:a, :b}) # Tuple {:a, :b}
f.([]) # Empty list
Кортеж
{ a, b, c } = { "Hello", "World", "!" }
IO.puts a # Hello
IO.puts b # World
IO.puts c # !
# Tuples of different size won't match:
{ a, b, c } = { "Hello", "World" } # (MatchError) no match of right hand side value: { "Hello", "World" }
Чтение файла
Согласование шаблонов полезно для операции, такой как чтение файла, которое возвращает кортеж.
Если файл sample.txt
содержит This is a sample text
, тогда:
{ :ok, file } = File.read("sample.txt")
# => {:ok, "This is a sample text"}
file
# => "This is a sample text"
В противном случае, если файл не существует:
{ :ok, file } = File.read("sample.txt")
# => ** (MatchError) no match of right hand side value: {:error, :enoent}
{ :error, msg } = File.read("sample.txt")
# => {:error, :enoent}
Учет соответствия анонимных функций
fizzbuzz = fn (0, 0, _) -> "FizzBuzz" (0, _, _) -> "Fizz" (_, 0, _) -> "Buzz" (_, _, x) -> x end my_function = fn(n) -> fizzbuzz.(rem(n, 3), rem(n, 5), n) end
Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow