【问题标题】:Type of non-terminating function in ErlangErlang中非终止函数的类型
【发布时间】:2016-09-08 03:47:55
【问题描述】:

我正在学习 Erlang,并尝试在可能的情况下使用 Dialyzer 来获得最大的类型安全性。有一件事我不明白:non-terminating 函数的类型是什么以及如何在-spec 中表示它。任何人都可以对此有所了解吗?

【问题讨论】:

    标签: types erlang dialyzer


    【解决方案1】:

    以下示例在 Elixir 中,但我相信它们在类型规范中使用 no_returnnone 对于 Erlangers 也很清楚:

     defmodule TypeSpecExamples do
       @moduledoc """
       Examples of typespecs using no_return and none.
       """
    
       @spec forever :: no_return
       def forever do
         forever()
       end
    
       @spec only_for_side_effects :: no_return
       def only_for_side_effects do
         IO.puts "only_for_side_effects"
         :useless_return_value # delete this line to return the value of the previous line
       end
    
       @spec print_dont_care :: no_return
       def print_dont_care do
         IO.puts("""
           A no_return function that does not loop always returns a value, \
           which can be anything, such as the atom #{only_for_side_effects()}
           """)
       end
    
       @spec always_crash :: none
       def always_crash do
         raise "boom!"
       end
    
       @spec value_or_crash(boolean) :: number | none
       def value_or_crash(b) do
         if b do
           1
         else
           raise "boom!"
         end
       end
    
     end
    

    【讨论】:

      【解决方案2】:

      永远循环且永不终止的函数的返回类型为no_return()。 (该返回类型也用于总是抛出异常的函数,例如自定义错误函数。如果您不指定该返回类型,Dialyzer 会告诉您该函数“没有本地返回”。)

      这在 Erlang 参考手册的Types and Function Specifications 章节中有所提及:

      Erlang 中的某些函数不打算返回;要么是因为它们定义了服务器,要么是因为它们被用来抛出异常,如下面的函数:

      my_error(Err) -> erlang:throw({error, Err}).
      

      对于此类函数,建议使用特殊的no_return() 类型作为它们的“返回”,通过以下形式的合约:

      -spec my_error(term()) -> no_return().
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-09
      • 2012-11-16
      • 1970-01-01
      • 2016-01-04
      • 2019-12-16
      • 2014-06-03
      • 1970-01-01
      • 2021-06-01
      相关资源
      最近更新 更多