Erlang(Elixir)Dialyzer-令人困惑的超类型错误 [英] Erlang (Elixir) Dialyzer - confusing supertype error

查看:103
本文介绍了Erlang(Elixir)Dialyzer-令人困惑的超类型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have defined an Elixir behaviour X. A callback start_link is spec'ed as:

@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 定义为:

In the client code Y that implements the behaviour, start_link is defined as:

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

Dialyzer不喜欢它。它说,

Dialyzer doesn't like it. It says,

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



问题1:



在继承方面,子类型扩展了超类型。因此,定义的行为(X)应该被视为超类型。实现行为(Y)的模块应视为子类型。显然Dialyzer应该提出这样的问题:

Question #1:

In terms of inheritance, subtypes extend supertypes. Therefore, the defined behaviour(X) should be considered supertype. Module implementing the behaviour(Y) should be considered subtype. Apparently Dialyzer should have asked the question:


#{'job_queue_name':= binary()}
的超类型(#{'job_queue_name':= _,'redis_url':= _,_ => _})

相反,它反过来问了一个问题。为什么?

Rather it asks the question the other way around. Why?

超类型的定义与OOP继承中的讨论相同吗?如果没有,那是什么?我试图在透析器的上下文中找到超类型的定义,但没有找到。

Is the definition of supertype in dialyzer the same as in discussion of OOP inheritance? If not, what is it then? I tried to find definition of supertype in the context of dialyzer but found none.

推荐答案

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

The error message is basically saying: You cannot require the additional redis_url key, since it was not declared in the type spec of the behaviour.

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

Dialyzer doesn't treat the behaviour and implementing module as types. It is specifically looking at the parameter to the callback.

将与#{'job_queue_name'相匹配的一组值: = _,'redis_url':= _,_ => _} 是将与#{'job_queue_name':= _}

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

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

Dialyzer will permit you to implement a callback with parameters that are supertypes of what was declared in the callback, since that ensures any code relying on the behaviour contract won't fail with a match error at runtime.

这篇关于Erlang(Elixir)Dialyzer-令人困惑的超类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆