标签: elixir

Shell代表二进制

我有以下声明

iex(5)> a = <<3>>
<<3>>
iex(6)> b = <<a::binary>>
<<3>>
Run Code Online (Sandbox Code Playgroud)

第一行,我创建了一个值为 3 的二进制文件。在第三行,我希望 shell 向我显示 00000011 而不是 3。我知道首先创建一个二进制文件(1.line)然后再次转换为二进制文件是没有意义的。但我期待 shell 显示 00000011 而不是 3。

当二进制像浮动一样

iex(7)> a = << 5.3 :: float  >>
<<64, 21, 51, 51, 51, 51, 51, 51>>
Run Code Online (Sandbox Code Playgroud)

我不明白,为什么它显示我这个数字?

elixir

0
推荐指数
1
解决办法
884
查看次数

如何同时定义多个模块?(宏尝试不起作用)

我需要我的所有模型来实现特定的协议。我目前的尝试是MyApp.Convert定义了这个宏的模块:

defmodule ConvertMacro do
  @moduledoc """
  All model structs need to implement the convert interface and must be added
  here.
  """

  defmacro defimpl_convert_for(modules) do
    Enum.map(modules, fn module ->
      quote do
        defimpl Units.Convert, for: unquote(module) do
          require Units

          def to_standard_metric(struct) do
            Units.to_standard_metric_for_struct(unquote(module), struct)
          end

          def to_user_data(struct) do
            Units.to_user_data_for_struct(unquote(module), struct)
          end
        end
      end
    end)
  end
end

ConvertMacto.defimpl_convert_for([MyApp.User, MyApp.Block])
Run Code Online (Sandbox Code Playgroud)

错误:

== Compilation error on file lib/protocols/units_convert.ex ==
** (UndefinedFunctionError) function ConvertMacro.defimpl_convert_for/1 is undefined or private. Did you mean one of:

      * …
Run Code Online (Sandbox Code Playgroud)

elixir

0
推荐指数
1
解决办法
386
查看次数

模块 Ecto.Query 未加载且无法找到

我正在尝试按照 Programming Phoenix 的书中的示例练习通过 elixir shell 导入 Ecto.Query,它给了我这个错误

iex> import Ecto.Query

** (CompileError) iex:3: module Ecto.Query is not loaded and could not be found
Run Code Online (Sandbox Code Playgroud)

有人知道这是否已被弃用或是否有其他方式导入它?

elixir phoenix-framework

0
推荐指数
1
解决办法
1969
查看次数

如何使用过多的嵌套来重构case语句

在许多情况下,我发现自己需要在结构本身及其字段上进行模式匹配,并在某些中间结果不为空时继续执行一些进一步的操作.

但是,结构本身可能是nil第一位的.这导致我编写了多个嵌套匹配,例如

experiment = Repo.get(Experiment, experiment_id)

case experiment do
  nil ->
    # Error 1

  _ ->
    case experiment.active do
      false -> # Error 2
      true -> 
        case Repo.all(assoc(experiment, :experiment_results)) do
          [] -> # Error 3
          results -> # Do stuffs
    end
end
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想编写没有那么多嵌套的代码.

我该如何重构代码?


(请注意,我原来的问题是关于结构上的模式匹配nil.我的实际用例比我原来提出的问题更广泛,因此我更新了问题.)

原始代码,AlekseiMatiushkin和Sheharyar的答案适用于:

experiment = Repo.get(Experiment, experiment_id)

case experiment do
  nil ->
    :error

  _ ->
    case experiment.active do
      false -> :error
      true -> # Do stuffs
    end
end
Run Code Online (Sandbox Code Playgroud)

functional-programming elixir pattern-matching phoenix-framework

0
推荐指数
1
解决办法
71
查看次数

Elixir:惯用地克隆列表

我总是可以做这样的事情:

new_list = Enum.map(old_list, fn x -> x end)
Run Code Online (Sandbox Code Playgroud)

当然,还有更多的平等或略微丑陋的方法。不知何故,我找不到复制列表的惯用方式。当然一定有办法。

copy list elixir

0
推荐指数
1
解决办法
96
查看次数

通过Elixir中的多个值进行地图分组

所以我有这张地图

    map = [
             %{id: 2, brand: "TUTU", reference: "1234"}, 
             %{id: 2, brand: "TUTU", reference: "4567"}, 
             %{id: 3, brand: "TOTO", reference: "789456"}
    ]
Run Code Online (Sandbox Code Playgroud)

我想按ID将其分组以获得类似以下内容:

    [
        %{
            id: 2,
            brand: "TUTU",
            reference: [
                 "1234",
                 "5845"
              ]
        },
        %{
             id: 3,
             brand: "TOTO",
             reference: [
                  "4587"
             ]
        }
    ]
Run Code Online (Sandbox Code Playgroud)

我试图用Enum.group_by这样

map
|> Enum.group_by(fn entry -> entry.brand end)
Run Code Online (Sandbox Code Playgroud)

但是结果看起来像这样:

    %{
      "TOTO" => [%{brand: "TOTO", id: 3, reference: "789456"}],
      "TUTU" => [
        %{brand: "TUTU", id: 2, reference: "1234"},
        %{brand: "TUTU", id: 2, …
Run Code Online (Sandbox Code Playgroud)

elixir

0
推荐指数
1
解决办法
169
查看次数

在Elixir中嵌套嵌套循环的更好方法

请提出将下面的C代码编写到长生不老药的更好的方法(更多长生不老药的方法)。

int some_num = 0;

for(int i = 0; i < 100; i++){
  for(int j = 0; j < 1000; j++){
    for(int k = 0; k < 10000; k++){
      some_num += 1;
    }
  }
}
printf("%d", some_num);
Run Code Online (Sandbox Code Playgroud)

可以通过获得收益的长生不老药并发来实现它吗?

编辑:有点背景,我对长生不老药仍然学习。该问题的主要动机是编写比应用并发更多的惯用e剂代码。

elixir

0
推荐指数
1
解决办法
166
查看次数

Elixir:我从一个简单的加法函数中得到一个错误

我在Elixir中创建了一个简单函数,该函数将元组的值加1。

我将模块命名为Test,并将函数命名为addToTuple。它采用一个参数,即元组本身。

def addToTuple({X,Y}) do 
   {X,Y+1}
end
Run Code Online (Sandbox Code Playgroud)

我通过iex编译了模块,并收到以下警告:

 warning: this expression will fail with ArithmeticError
  Test.ex:68
Run Code Online (Sandbox Code Playgroud)

第68行引用了{X,Y + 1}。当我使用命令Test.addToTuple({4,5})运行该函数时,我不断收到此错误:

** (FunctionClauseError) no function clause matching in Test.addToTuple/1

    The following arguments were given to Test.addToTuple/1:

        # 1
        {4, 5}

    Test.ex:67: Test.addToTuple/1
Run Code Online (Sandbox Code Playgroud)

我期望得到{4,6}。

知道这里发生了什么吗?

更新1:

我将X和Y更改为小写,并且有效。但是,这次我对函数进行了一些修改,使其可以与原子一起使用:

def addToTuple({A,x,y}) do 
    {A,x,y+1}
end
Run Code Online (Sandbox Code Playgroud)

然后,我使用以下命令调用该函数:Test.addToTuple({:F,4,5})。我期待得到{:F,4,6}。但是,我得到了这个错误:

** (FunctionClauseError) no function clause matching in Test.addToTuple/1

    The following arguments were given to Test.addToTuple/1:

        # 1
        {:F, 4, 5}

    Test.ex:67: Test.addToTuple/1
Run Code Online (Sandbox Code Playgroud)

我以为使用大写字符会被视为原子?如何解决?

elixir

0
推荐指数
1
解决办法
83
查看次数

当前状态章当前状态Phoenix 1.4.6指南针对标识符“ socket”的加注已经声明

我正在阅读《凤凰城指南》 1.4.6,并且正在“ 存在”这一章中。因此,我遵循本章的所有步骤,而我的控制台javascript对此有所抱怨:

app.js:1 Uncaught Error: Module build failed: SyntaxError: /Users/romenigld/workspace/phoenix/hello/assets/js/app.js: Identifier 'socket' has already been declared (21:4)

  19 | import {Socket, Presence} from "phoenix"
  20 | 
> 21 | let socket = new Socket("/socket", {
     |     ^
  22 |   params: {user_id: window.location.search.split("=")[1]}
  23 | })
  24 | 
    at Parser.raise (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:6322)
    at ScopeHandler.checkRedeclarationInScope (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:3754)
    at ScopeHandler.declareName (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:3720)
    at Parser.checkLVal (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:8006)
    at Parser.parseVarId (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:10441)
    at Parser.parseVar (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:10412)
    at Parser.parseVarStatement (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:10234)
    at Parser.parseStatementContent (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:9830)
    at Parser.parseStatement (:4000/Users/romenigld/workspace/phoenix/hello/assets/node_modules/@babel/parser/lib/index.js:9763)
    at Parser.parseBlockOrModuleBlockBody …
Run Code Online (Sandbox Code Playgroud)

elixir elixir-framework phoenix-framework phoenix-channels

0
推荐指数
1
解决办法
53
查看次数

如何舍入到下一个1000值?

我想四舍五入到下一个1000值,总是四舍五入。

输入示例:

1 -> 1000
440 -> 1000
1001 -> 2000
14399 -> 15000
108 030 -> 109 000
Run Code Online (Sandbox Code Playgroud)

我只能找到一个与我无关的Float.ceil函数。

elixir

0
推荐指数
1
解决办法
58
查看次数