如何让Julia在分配时检测出不兼容的类型?

时间:2014-07-07 00:39:44

标签: julia

对不起基本问题,到目前为止谷歌搜索并没有太大用处。

我是新手。我想询问Julia是否可以自动检测分配中不兼容的类型。

例如,当我写

julia> x=10;
julia> typeof(x)
Int32

julia> y=9.0;    
julia> typeof(y)
Float64

julia> x=y // I'd like this to generate an error or a warning at least
9.0

julia> typeof(x) // do not want automatic type conversion
Float64

我发现如果将作业更改为

julia> (x=y)::Int32
ERROR: type: typeassert: expected Int32, got Float64

但我不想一直写这个,并希望Julia自动检测到这一点。 我试着在下面做这样的声明,但我似乎做错了。

julia> x::Int32=10;
julia> y::Float64=9.0
ERROR: type: typeassert: expected Float64, got Int32

例如,在Java中,这会生成编译错误:

public class App{   
    public static void main (String[] args) {
        int x=10;
        double y=9.0;
        x=y;
    }
}
error: incompatible types: possible lossy conversion from double to int x=y;

为了实现这一目标,我需要做些什么改变?我需要在之前使用正确的类型声明x,y吗?怎么样?我在Linux上使用Julia 0.3。

1 个答案:

答案 0 :(得分:2)

变量表示的值可以限定为始终具有特定类型,并且将检查不兼容的值,但是在运行时检查此违规。来自documentation

  

当附加到语句上下文中的变量时,::运算符意味着有点不同:它声明变量总是具有指定的类型,就像静态类型语言中的类型声明,例如C.每个值分配给变量将使用convert函数转换为声明的类型。

这是一个重要的警告,但

  

目前,类型声明不能在全局范围内使用,例如在REPL中,因为Julia还没有常量类型的全局变量。

因此您的实验不起作用,因为您正在使用全局变量。但是,使用函数作用域中的变量来键入断言。

以你的榜样为例

案例I

julia> main()=(x::Int64=10;y::Float64=9.0;x=y)
main (generic function with 1 method)

julia> main()
9.0

看起来错误的事情发生了,但是函数的结果是最后一个表达式的评估。所以在案例I中,赋值表达式返回 Float64 值,但 x 仍然被隐式赋值 9.0 转换为 Int64 9 。但在案例II中,最后一个表达式只是 x ,即 Int64

案例II

julia> main()=(x::Int64=10;y::Float64=9.0;x=y;x)
main (generic function with 1 method)

julia> main()
9

julia> typeof(main())
Int64

y 接受converted而不会丢失 Int64 的值时,会抛出错误

案例III

julia> main()=(x::Int64=10;y::Float64=9.9;x=y;x)
main (generic function with 1 method)

julia> main()
ERROR: InexactError()
 in main at none:1

The Guts

您可以使用 code_typed 功能查看更准确的内容。请考虑以下事项:

julia> f(y::Float64)=(x::Int64=y)
f (generic function with 1 method)

julia> code_typed(f,(Float64,))
1-element Array{Any,1}:
 :($(Expr(:lambda, {:y}, {{:x},{{:y,Float64,0},{:x,Int64,18}},{}}, :(begin  # none, line 1:
        x = top(typeassert)(top(box)(Int64,top(checked_fptosi)(Int64,y::Float64))::Int64,Int64)::Int64
        return y::Float64
    end::Float64))))

julia> f(y::Float64)=(x::Int64=y;x)
f (generic function with 1 method)

julia> code_typed(f,(Float64,))
1-element Array{Any,1}:
 :($(Expr(:lambda, {:y}, {{:x},{{:y,Float64,0},{:x,Int64,18}},{}}, :(begin  # none, line 1:
         x = top(typeassert)(top(box)(Int64,top(checked_fptosi)(Int64,y::Float64))::Int64,Int64)::Int64
        return x::Int64
    end::Int64))))