【问题标题】:Julia: Even-number datatype for functionsJulia:函数的偶数数据类型
【发布时间】:2020-04-10 05:25:03
【问题描述】:

我有大约 50 个函数,它们应该只消耗偶数正数。现在我每次都用“如果”检查输入的数字是否为零:

function grof(x::Int)
    if (x % 2) == 0
        println("good")
    else
        throw("x is not an even number!!!!!!!!!!!!! Stupid programmer!")
    end
end

理想情况下,我希望有一个自动生成的数据类型,即

function grof(x::EvenInt)
    println("good")  
end

但是,我无法自己生成此数据类型,因为我无法理解 documentary。感谢您的帮助!

最好的,v.

【问题讨论】:

    标签: julia


    【解决方案1】:

    我认为在这种情况下创建类型是没有必要的:我只想@assert 在函数开头验证条件。 (有趣的是,检查数字是否为偶数是文档中选择的示例来说明@assert的效果)

    例如:

    julia> function grof(x::Int)
               @assert iseven(x) "Stupid programmer!"
               println("good")
           end
    grof (generic function with 1 method)
    
    julia> grof(2)
    good
    
    julia> grof(3)
    ERROR: AssertionError: Stupid programmer!
    Stacktrace:
     [1] grof(::Int64) at ./REPL[5]:2
     [2] top-level scope at REPL[7]:1
    




    编辑:如果您真的想要创建一个强制执行此类约束的类型,这是可能的。这样做的方法是

    1. 创建一个类型(可能是 Number 抽象类型之一的子类型;可能是 Signed
    2. 定义一个内部构造函数,确保此类类型不能保存奇数值

    一个非常简单的例子是:

    # A wrapper around an even integer value
    struct EvenInt
        val :: Int
    
        # inner constructor
        function EvenInt(val)
            @assert iseven(val)
            new(val)
        end
    end
    
    # Accessor to the value of an EvenInt
    val(x::EvenInt) = x.val
    
    # A method working only on even numbers
    grof(x::EvenInt) = println("good: $(val(x)) is even")
    

    你会这样使用它:

    julia> x = EvenInt(42)
    EvenInt(42)
    
    julia> grof(x)
    good: 42 is even
    
    julia> y = EvenInt(1)
    ERROR: AssertionError: iseven(val)
    Stacktrace:
     [1] EvenInt(::Int64) at ./REPL[1]:5
     [2] top-level scope at REPL[6]:1
    

    但请注意,您还不能在 EvenInts 上做任何事情:您需要解开它们(在这种情况下使用 val()),或者定义对它们的操作(如果您使用该任务可以大大简化使EvenInt成为其中一种抽象数字类型的子类型,并遵循相关接口)。

    【讨论】:

    • 你看起来很失望,所以我添加了一个示例,说明如果你真的想定义这样的类型。
    • 这不是类型系统的用途。通常,您希望将类型用于易于静态推理的事物。静态推理一个值是否偶数有时是可能的,但通常不是。在这种情况下,检查均匀度非常便宜且清晰。为什么最好得到一个方法错误?
    【解决方案2】:

    所有乘以 2 的整数都是偶数,因此请重新定义您的函数,使其取当前数字的一半。

    function grof2(halfx::Int)
           x=2*halfx
           println("good")
    end
    

    【讨论】:

    • 或者甚至将其用作EvenInt的内部表示。
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2022-07-08
    • 2016-04-28
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多