You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
не е задължително, но лесно ще си взимате домашното/информацията
Малко предговор
Elixir се компилира до:
a) JavaScript
b) Java
c) Erlang
d) Machine Code
Малко предговор
Elixir:
a) е статично-типизиран?
b) е динамично-типизиран?
c) имплементира Actor модела?
d) има строга типизация (Strongly typed)?
e) има слаба типизация (Weakly typed)?
f) използва кооперативно планиране (Cooperative scheduling)?
g) използва превантивно планиране (Preemptive scheduling)
Модули и функции
Дефиниране на модул
defmoduleTimesdodefdouble(n)don*2endend
Компилиране
като използваме elixirc times.ex
може да ползваме и iex times.ex за удобство
ще генерира файл на име Elixir.Times.beam, който съдържа байткода
iex автоматично ще зареди всякакви *.beam файлове, ако са в същата директория
никога няма да го правим по този начин
Забелязвате ли префикса Elixir. ?
Компилиране и зареждане на файл от конзолата
iex(1)> c "times.ex"
[Times]
iex(2)> Times.double(10)
20
.ex vs .exs
.ex е за файлове, които искаме да се компилират.
.exs е за файлове, които са скриптове и ще изпълняваме.
elixirc vs elixir
elixirc само компилира код до .beam
elixir ще компилира в паметта и изпълни дадения файл, няма да произведе .beam файл
компилират кода по един и същ начин
Функции
Публични фукнции дефинираме с def/2
макрос е (ще имаме поне 2 лекции за макроси)
публичните функции могат да се извикват от други модули
{Частни, поверителни, За собствено ползване} фукнции дефинираме с defp/2
пак е макрос
могат да се извикват само вътре в даден модул
компилаторът може да се оплаче само за private функции, които не ползваме
Пример
defmodule FMI do
def смятай(a, b) do
смятай_бре(a, b)
end
defp смятай_бре(a, b) do
a + b
end
end
IO.puts(FMI.смятай(3, 4)) # => 7
IO.puts(FMI.смятай_бре(3, 4))
# => ** (UndefinedFunctionError) function FMI.смятай_бре/2 is undefined or private.
Функции с различен брой параметри
iex(1)> String.split("Elixir is awesome. It totally kicks bum.")
["Elixir", "is", "awesome.", "It", "totally", "kicks", "bum."]
iex(2)> String.split(
"Foo Bar Baz",
"",
parts: 2)
["Foo", "Bar Baz"]
do..end блокове с малко код
# Кратък синтаксис за one-linersdefdouble(n),do: n*2# do..end синтаксис, позволява много редове кодdefagain_double(n)don*2end
defmoduleOuterdodefmoduleInnerdodefinner_funcdo"hello world"endenddefouter_funcdo"Greeting from the inner func: #{Outer.Inner.inner_func}"endendOuter.outer_func# => "Greeting from the inner func: hello world"Outer.Inner.inner_func# => "hello world"
Няма нищо специално за вложените модули
само синтактична захар
крайните модули ще са :"Elixir.Outer" и :"Elixir.Outer.Inner"
пак трябва да импортираме функциите от бащата модул във вложения модул
defmoduleDeep.Outerdodefouter,do: :outerdefmoduleInnerdo# Трябва Deep.Outer.outer/1 да го реферираме директно,# ще гръмнеdefinner_outer,do: Outer.outer()# Няма да се компилираdefinner_outer2,do: outer()endend
Между другото нищо не ни пречи директно да направим това:
# Using only:defmoduleCsvUtilsdoimportString,only: [upcase: 1,split: 2,strip: 1]defupcase_space_transform(csv_line)docsv_line|>upcase|>split(",")|>Enum.map(&strip/1)|>Enum.join(" ")endend
# Using except:defmoduleRationalNumbersdoimportKernel,except: [abs: 1]defabs({n,d}),do: {Kernel.abs(n),Kernel.abs(d)}end
defmoduleFoododefhi,do: "Hi from Foo"enddefmoduleBardodefhi,do: "Hi from Bar"enddefmoduleBazdoimportFooimportBardefsay_hi,do: hi()end# ** (CompileError) iex:16: function hi/0 imported from both Bar and Foo, call is ambiguous# (elixir 1.12.3) src/elixir_dispatch.erl:128: :elixir_dispatch.expand_import/6# (elixir 1.12.3) src/elixir_dispatch.erl:91: :elixir_dispatch.dispatch_import/5# iex:16: (module)
alias
дава алтернативно име на модул, за да го използваме по-удобно.
указваме новото име с as: <name> - alias Some.Other.Module, as: M
ако не укажем as:, то частта от името след последната точка се използва
можем да преименуваме ерлангски модули: alias :rand, as: Random
{синтаксис}
defmoduleOuter.Innerdodefinner_funcdo"hello world"endenddefmoduleOuterdoaliasOuter.Inner,as: Innerdefouter_funcdo"Greeting from the inner func: #{Inner.inner_func}"endend
defmoduleOuterdodefmoduleFoododefhi,do: "Hi from Foo"enddefmoduleBardodefhi,do: "Hi from Bar"endendaliasOuter.{Foo,Bar}Foo.hi()# => "Hi from Foo"Bar.hi()# => "Hi from Bar"
require & use
използват се когато искаме да използваме макроси дефинирани в даден модул
compile time ще се "разшири" макроса
повече за require/use когато стигнем до мета-програмирането
имат и други приложения, повече за тях по време на мета-програмирането
defmoduleGreeterdo@moduledoc""" A module designed to greet strangers and friends alike! """@standard_greeting"Hello, stranger!"@doc"Greet someone!"defgreet(nil)doIO.puts@standard_greetingenddefgreet(name)doIO.puts"Hello, #{name}!"endend
Анонимни функции
всъщност може да ви покажем само анонимни функции и това е достатъчно за целия курс