gpt4 book ai didi

Erlang (Elixir) Dialyzer - 令人困惑的父类(super class)型错误

转载 作者:行者123 更新时间:2023-12-02 05:22:55 25 4
gpt4 key购买 nike

我定义了 Elixir 行为 X。回调 start_link 指定为:

@callback start_link(
args :: producer_args,
opts :: GenServer.options
) :: GenServer.on_start

其中 Producer_args 类型定义为:

@type producer_args :: %{job_queue_name: String.t}

在实现该行为的客户端代码Y中,start_link定义为:

def start_link(args = %{job_queue_name: _job_queue_name, redis_url: _redis_url}, opts) do
GenStage.start_link(__MODULE__, args, opts)
end

透析器不喜欢它。它说,

(#{'job_queue_name':=_, 'redis_url':=_, _=>_}) 
is not a supertype of
#{'job_queue_name':=binary()}

问题#1:

就继承而言,子类型扩展了父类(super class)型。因此,定义的行为(X)应该被视为父类(super class)型。实现行为(Y)的模块应被视为子类型。显然 Dialyzer 应该问这个问题:

Is #{'job_queue_name':=binary()} a supertype of (#{'job_queue_name':=_, 'redis_url':=_, _=>_})?

相反,它以相反的方式提出问题。为什么?

问题#2:

dialyzer中supertype的定义与OOP继承中的定义相同吗?如果不是,那是什么?我试图在透析器的上下文中找到父类(super class)型的定义,但没有找到。

最佳答案

错误消息基本上是说:您不能要求额外的 redis_url关键,因为它没有在行为的类型规范中声明。

Dialyzer 不将行为和实现模块视为类型。它专门查看回调的参数。

将与 #{'job_queue_name':=_, 'redis_url':=_, _=>_} 匹配的值集是将与 #{'job_queue_name':=_} 匹配的值的子集.

所以#{'job_queue_name':=_, 'redis_url':=_, _=>_}#{'job_queue_name':=_} 的子类型.

Dialyzer 将允许您使用回调中声明的参数的父类(super class)型来实现回调,因为这可以确保依赖行为协定的任何代码都不会在运行时因匹配错误而失败。

关于Erlang (Elixir) Dialyzer - 令人困惑的父类(super class)型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46246998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com