Elixir函数首个参数设默认值后为何可接必填参数?
为什么Elixir函数首个参数带默认值还能跟必填参数?
这是Elixir默认参数机制的特性——编译器会自动生成重载的函数子句,来适配不同的参数传入情况。
你贴的这个changeset函数,编译器会偷偷帮你生成两个函数子句:
# 子句1:接收完整的两个参数,无默认值 def changeset(model, params) do model |> cast(params, @required_fields ++ @optional_fields) |> validate_required(@required_fields) end # 子句2:只接收params参数,自动使用model的默认值调用子句1 def changeset(params) do changeset(%__MODULE__{}, params) end
所以实际调用时:
- 当你只传一个参数(比如
changeset(%{name: "张三"})),会触发第二个子句,自动把model设为默认的空结构体%__MODULE__{}; - 当你传两个参数(比如
changeset(existing_user, %{name: "李四"})),会直接走第一个子句,用你传入的model和params。
这种写法在Ecto的业务场景里特别实用:大部分时候是基于空结构体创建新数据的changeset,只传参数就行;需要修改已有数据时,再传入原结构体和更新参数,兼顾了简洁性和灵活性。
内容的提问来源于stack exchange,提问作者mandiromi
相关产品推荐
相关产品推荐

