markdown Elixir随机笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Elixir随机笔记相关的知识,希望对你有一定的参考价值。
An important feature of Elixir is that any two types can be compared; this is particularly useful in sorting. We don’t need to memorize the sort order, but it is important to be aware of it:
*number < atom < reference < function < port < pid < tuple < map < list < bitstring*
Elixir implements list collections as linked lists. This means that accessing the list length is an operation that will run in linear time (O(n)). For this reason, it is typically faster to prepend than to append.
## Head / Tail
```elixir
hd [3.14, :pie, "Apple"]
tl [3.14, :pie, "Apple"]
[head | tail] = [3.14, :pie, "Apple"]
```
## Tuples
Tuples are similar to lists, but are stored contiguously in memory. This makes accessing their length fast but modification expensive; the new tuple must be copied entirely to memory.
```elixir
iex> {3.14, :pie, "Apple"}
iex> File.read("path/to/existing/file")
{:ok, "... contents ..."}
iex> File.read("path/to/unknown/file")
{:error, :enoent}
```
## Keyword lists
```elixir
iex> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex> [{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
```
The three characteristics of keyword lists highlight their importance:
* Keys are atoms.
* Keys are ordered.
* Keys may not be unique.
For these reasons, keyword lists are most commonly used to pass options to functions.
## Maps
In Elixir, maps are the “go-to” key-value store. Unlike keyword lists, they allow keys of any type and are un-ordered.
```elixir
iex> map = %{:foo => "bar", "hello" => :world}
iex> map[:foo]
iex> %{:foo => "bar", :foo => "hello world"}
%{foo: "hello world"}
iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
true
```
there is a special syntax for maps containing only atom keys:
```elixir
iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
```
In addition, there is a special syntax for accessing atom keys:
```elixir
iex> map.hello
"world"
```
Another interesting property of maps is that they provide their own syntax for updates:
```
iex> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
```
For a full list of functions visit the official [Enum](https://hexdocs.pm/elixir/Enum.html) docs; for lazy enumeration use the [Stream](https://hexdocs.pm/elixir/Stream.html) module.
## Pin Operator
[Lesson](https://elixirschool.com/en/lessons/basics/pattern-matching/#pin-operator)
The match operator performs assignment when the left side of the match includes a variable. In some cases this variable rebinding behavior is undesirable. For these situations we have the pin operator: ^. When we pin a variable we match on the existing value rather than rebinding to a new one.
```elixir
iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand side value: 2
iex> {x, ^x} = {2, 1}
{2, 1}
iex> x
2
```
Elixir 1.2 introduced support for pins in map keys and function clauses.
## Modules
[Lesson](https://elixirschool.com/en/lessons/basics/modules/)
## Mix
```elixir
def deps do
[
{:phoenix, "~> 1.1 or ~> 1.2"},
{:phoenix_html, "~> 2.3"},
{:cowboy, "~> 1.0", only: [:dev, :test]},
{:slime, "~> 0.14"}
]
end
```
```bash
$ mix deps.get
```
The current environment can be accessed using Mix.env. As expected, the environment can be changed via the MIX_ENVenvironment variable:
$ MIX_ENV=prod mix compile
## Sigils
[Lesson](https://elixirschool.com/en/lessons/basics/sigils/)
## Documentation
* https://elixirschool.com/en/lessons/basics/documentation/#best-practice
* https://hexdocs.pm/ex_unit/ExUnit.DocTest.html
* https://github.com/christopheradams/elixir_style_guide
Always document a module. If you do not intend to document a module, do not leave it blank. Consider annotating the module false:
```elixir
@moduledoc false
```
## Testing
* `assert`
* `assert_raise`
* `assert_received` does not wait for messages, with assert_receive you can specify a timeout.
* `capture_io`
* `capture_log`
* Use `refute` when you want to ensure a statement is always false.
### Test setup
* `setup`
* `setup_all`
```elixir
defmodule ExampleTest do
use ExUnit.Case
doctest Example
setup_all do
{:ok, recipient: :world}
end
test "greets", state do
assert Example.hello() == state[:recipient]
end
end
```
### Mocking
The simple answer to mocking in Elixir is: don’t. You may instinctively reach for mocks but they are highly discouraged in the Elixir community and for good reason.
For a longer discussion there is this [excellent article](http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/). The gist is, that instead of mocking away dependencies for testing (mock as a verb), it has many advantages to explicitly define interfaces (behaviors) for code outside your application and using Mock (as a noun) implementations in your client code for testing.
To switch the implementations in your application code, the preferred way is to pass the module as arguments and use a default value. If that does not work, use the built-in configuration mechanism. For creating these mock implementations, you don’t need a special mocking library, only behaviours and callbacks.
以上是关于markdown Elixir随机笔记的主要内容,如果未能解决你的问题,请参考以下文章