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随机笔记的主要内容,如果未能解决你的问题,请参考以下文章

markdown elixir_note.md

markdown 凤凰随机笔记

如何在 Elixir 中生成随机数?

如何从 Erlang/Elixir 中的 ets 集中选择一个随机元素?

为啥元组在 Elixir 中不可枚举?

将本地 Elixir/Erlang 连接到 Docker 容器内正在运行的应用程序