【发布时间】:2021-02-16 21:09:38
【问题描述】:
我有以下代码:
defmodule Foo do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
@type t :: %__MODULE__{
id: integer(),
foo: String.t(),
baz_id: String.t(),
bar: String.t() | nil
}
embedded_schema do
field :foo, :string
field :bar, :string
end
@spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
def changeset(bae \\ %__MODULE__{}, attrs) do
bae
|> cast(attrs, @fields)
|> unique_constraint(:baz_id)
end
end
foo 和 baz_id 不应为 nil,根据 @type 定义。
但是,dialyzer 正在抱怨(使用给定的 @spec),因为默认值 %__MODULE__{} 会将它们设置为 nil。
如果我将 @type 定义替换为:
...
@type t :: %__MODULE__{
id: integer() | nil,
foo: String.t() | nil,
baz_id: String.t() | nil,
bar: String.t() | nil
}
...
那么dialyzer 不会抱怨,但我不再认为某些字段不可为空。
什么是让changeset() 以目前的方式工作并避免dialyzer 抱怨这种特定用途的优雅方式?
【问题讨论】:
标签: types elixir dialyzer typespec