[英]`changeset()` spec requires nullable type which is not logically nullable
I have the following code:我有以下代码:
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
and baz_id
should not be nil
, as per the @type
definition.根据
@type
定义, foo
和baz_id
不应为nil
。 However, dialyzer
is complaining (with the given @spec
) because the default value %__MODULE__{}
will set them to nil
.但是,
dialyzer
抱怨(使用给定的@spec
),因为默认值%__MODULE__{}
会将它们设置为nil
。
If I replace the @type
definition with:如果我将
@type
定义替换为:
...
@type t :: %__MODULE__{
id: integer() | nil,
foo: String.t() | nil,
baz_id: String.t() | nil,
bar: String.t() | nil
}
...
then dialyzer
will not complain, but I am no longer capturing the idea that some of the fields are not nullable.那么
dialyzer
不会抱怨,但我不再认为某些字段不可为空。
What would be an elegant way to make changeset()
work the way it currently is, and avoid having dialyzer
complaining for this specific use?什么是让
changeset()
以目前的方式工作并避免dialyzer
抱怨这种特定用途的优雅方法?
Well, you're explicitly specifying the default argument that violates a dialyzer contract (the schema is a bare struct underneath without default values,) that's why dialyzer complains.好吧,您明确指定了违反透析器合同的默认参数(架构是下面没有默认值的裸结构),这就是透析器抱怨的原因。
It is unclear, how you do suppose to handle an empty %__MODULE__{}
once it's not allowed, but answering the question stated, the workaround would be to accept nil
argument as a default.目前尚不清楚,一旦不允许,您应该如何处理空的
%__MODULE__{}
,但回答所述问题时,解决方法是接受nil
参数作为默认值。
@spec changeset(
nil | t() | Ecto.Changeset.t(), map()
) :: Ecto.Changeset.t()
def changeset(bae \\ nil, attrs) do
bae
|> Kernel.||(%__MODULE__{})
|> cast(attrs, @fields)
|> unique_constraint(:baz_id)
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.