代码之家  ›  专栏  ›  技术社区  ›  Brett Beatty

检查模块是否执行操作

  •  0
  • Brett Beatty  · 技术社区  · 6 年前

    MyBehaviour.implemented_by?/1 但我想知道有没有更直接的方法。

    defmodule MyBehaviour do
      @callback do_something(String.t(), String.t()) :: no_return()
    
      def implemented_by?(module) do
        :attributes
        |> module.module_info()
        |> Enum.member?({:behaviour, [__MODULE__]})
      end
    end
    

    我在医生或长生不老药论坛或任何地方都找不到任何东西。

    我应该检查一下吗? 或者我应该让责任完全落在打电话的人身上?行为是否更像是“我想确保我实现了所有需要的东西”而不是“我想让其他人知道我实现了所有需要的东西”?

    我的函数规范是否可以说args应该实现我的行为,或者我应该使用 module()/atom()

    0 回复  |  直到 6 年前
        1
  •  5
  •   Adam Millerchip    6 年前

    有趣的问题。

    行为函数的关键字是 @callback

    您提供运行时警告的解决方案在我看来很好—但是可以在不提供 @behaviour 属性,所以在这种情况下它不会很好地工作。

    如果行为实现者声明 @行为

    警告:Behavior ExpectBehavior所需的函数foo/0未实现(在模块ClaimsImplementsButDoesNot中)

    iex> ExpectBehaviour.use_behaviour(ClaimsItImplementsButDoesNot)
    ** (UndefinedFunctionError) function ClaimsItImplementsButDoesNot.foo/0 is undefined or private,
       but the behaviour ExpectBehaviour expects it to be present
    

    但是,如果您只是传递一个不实现行为的无关模块,则情况并非如此:

    iex> ExpectBehaviour.use_behaviour(DoesNotImplementOrClaimTo)
    ** (UndefinedFunctionError) function DoesNotImplementOrClaimTo.foo/0 is undefined or private
    

    有没有一种方法可以在typespecs中使用行为作为类型?

    行为不是类型,而是一组函数的规范,一个模块可以实现多个行为,所以我认为这没有意义。如上所述,将行为回调的使用限制在定义它的模块上似乎是明智的。