Reputation: 20774
In C++ you can write:
double x = 0.0, y = 0.0, z = 0.0;
instead of:
double x = 0.0; double y = 0.0; double z = 0.0;
to define three variables of the same type, double
in this example.
In Julia, the analogous would be:
x::Float64 = 0.0, y::Float64 = 0.0, z::Float64 = 0.0
Is there a syntactic sugar, like the above for C++, allowing me to omit the the three type specifiers, replacing them with just one when they are all the same?
Note: I know I can just write
x = y = z = 0.0
and let Julia infer the type. This is not what I want. I want to state explicitly that the types of x,y,z
are constant.
Upvotes: 3
Views: 3519
Reputation: 1750
Actually, the following doesn't declare those as variables in Julia
x::Float64, y::Float64, z::Float64
At least based on my investigation, you'd need something more like:
local x::Float64 = zero(Float64)
local y::Float64 = zero(Float64)
local z::Float64 = zero(Float64)
There is no syntactic sugar for doing that, AFAIK, forcing a particular type is not that common or necessary in Julia.
EDIT: I should be clearer, esp. after @dpsanders comment below, that I don't feel this is something that should normally ever be done in Julia, and even though type assertions can be useful for performance reasons in limited cases, using them so much you want syntactic sugar or a macro to shorten the code seems like a case of premature optimization.
If you really want to do that a lot, you can write a macro to take care of it for you, like the following:
macro dcl(T, args...)
r = quote end
for var in args
push!(r.args, :( local $(esc(var))::$T = zero($T)) )
end
r
end
I'm sure some Julian with more macro-"fu" than me can do a much better job, but it does seem to work, in my testing, i.e.:
@dcl(Float64, x, y, z)
Edit: The following demonstrates that the syntax doesn't declare any variables at all, just constrains the types of variables taken from the enclosing scope:
julia> function testdecl()
x::Float64, y::Int, z::String
println(x, y, z)
end
testdecl (generic function with 1 method)
julia> @code_warntype testdecl()
Variables:
#self#::#testdecl
Body:
begin # REPL[107], line 2:
(Core.typeassert)(Main.x,Main.Float64)::Float64
(Core.typeassert)(Main.y,Main.Int)::Int64
(Core.typeassert)(Main.z,Main.String)::String # REPL[107], line 4:
return (Main.println)(Main.x,Main.y,Main.z)::Any
end::Any
I'm wondering if there may also be a bug here, looking at the following:
julia> function testdcl()
println(y)
x::Float64, y::String
x = 1
println(x)
end
testdcl (generic function with 1 method)
julia> y = 1.234
1.234
julia> testdcl()
1.234
ERROR: UndefVarError: x not defined
in testdcl() at ./REPL[131]:2
in eval(::Module, ::Any) at ./boot.jl:226
julia> @code_warntype testdcl()
Variables:
#self#::#testdcl
x::Union{}
Body:
begin # REPL[131], line 1:
(Main.println)(Main.y)::Any # REPL[131], line 2:
(Core.tuple)((Core.typeassert)(x::Union{},Main.Float64)::Union{},(Core.typeassert)(Main.y,Main.String)::String)::Union{}
end::Union{}
Upvotes: 2
Reputation: 12644
Variables don't have types in Julia. Values have types.
But you can use const
to ensure that a variable cannot be assigned a value of a different type. Here's one way, though it may not be the most concise:
const a, b, c = (zeros(Float64, 3)...)
Edit: But are you sure this is what you really want? Julia is a dynamically typed language, and what you're asking is something you normally do in a statically typed language.
Upvotes: 1