# \`read!\` and scalar variables

**URL:** <https://discourse.julialang.org/t/read-and-scalar-variables/86619>\
**Category:** General Usage\
**Created:** [August 31, 2022, 8:51pm UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619 "2022-08-31T20:51:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ChauhanT](https://avatars.discourse-cdn.com/v4/letter/c/f0a364/32.png) [@ChauhanT](https://discourse.julialang.org/u/ChauhanT)\
**Post date:** [August 31, 2022, 8:51pm UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619/1 "2022-08-31T20:51:00Z")

</div>

Hi,

Is there a specific reason why `read!` does not accept scalars ? The signature allows for the `AbstractArray` type, but not scalars.

So essentially, this works:

```nohighlight
ios = open("./proprietary.format")
ver = Array{UInt32}(undef,1)
read!(ios,ver)

```

While this does not:

```nohighlight
ios = open("./proprietary.format")
ver = Array{UInt32}(undef,0)
read!(ios,ver)

```

I’m very curious about what the reasoning behind this is. It will probably also help me write safer code.

Thanks!

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [August 31, 2022, 9:28pm UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619/2 "2022-08-31T21:28:34Z")

</div>

> [@ChauhanT](#):
>
> Is there a specific reason why `read!` does not accept scalars ? The signature allows for the `AbstractArray` type, but not scalars.

`read!` is the mutating version of `read`, the `!` bang indicating that it changes the contents of its argument. For `AbstractArray` types, this makes sense, as an array passed into the function can have its contents modified by the function.

The scalar types that Julia has support for reading from files don’t have such mutable internals i.e. you can’t pass an `x::Int` to a function and have `x`’s value modified by the function after the call. So the scalar types `Int`, `Float64`, `Complex`, etc. have `read(io, Type)` methods rather than mutating `read!` methods.

> [@ChauhanT](#):
>
> While this does not:
> 
> ```julia
> ver = Array{UInt32}(undef,0)
> 
> ```

This is a zero-length array that cannot store any content. Perhaps you intended to create a zero-dimensional array instead? For those, `read!` does work:

```julia
julia> ver = Array{UInt32, 0}(undef)
0-dimensional Array{UInt32, 0}:
0x00000000

julia> read!(ios, ver)
0-dimensional Array{UInt32, 0}:
0x68542023

```

---

<div class="post-metadata">

**Author:** ![ChauhanT](https://avatars.discourse-cdn.com/v4/letter/c/f0a364/32.png) [@ChauhanT](https://discourse.julialang.org/u/ChauhanT)\
**Post date:** [August 31, 2022, 9:54pm UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619/3 "2022-08-31T21:54:16Z")

</div>

That was very informative, thank you! I have a small follow-up: are these zero-dimensional arrays equivalent to scalars?

EDIT: Also, how does one initialise a scalar in a manner analogous to `x = Array{Int32,1}(undef,5)` or `x = Array{UInt32,0}(undef)` ?

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [September 1, 2022, 6:56am UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619/4 "2022-09-01T06:56:31Z")

</div>

> [@ChauhanT](#):
>
> are these zero-dimensional arrays equivalent to scalars?

Well, in the sense that they only contain a single instance in them, they are equivalent to us. But to Julia’s type system, they are distinct things. So a function that accepts a `UInt32` won’t accept the `Array{UInt32, 0}` constructed above.

In practice, zero-dimensional arrays are rarely used, and scalars are much more common.

> [@ChauhanT](#):
>
> Also, how does one initialise a scalar in a manner analogous to `x = Array{Int32,1}(undef,5)` or `x = Array{UInt32,0}(undef)` ?

It’s usually not necessary, but you _can_ use the `local` keyword. From [the manual](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Local-Scope):

> `local x` declares a new local variable in that scope, regardless of whether there is already a variable named `x` in an outer scope or not. Declaring each new variable like this is somewhat verbose and tedious, however, so Julia, like many other languages, considers assignment to a variable name that doesn’t already exist to implicitly declare that variable.

The normal way to create a scalar is to just assign to it, `x = 5.0` creates a new `Float64` variable `x` automatically (assuming `x` doesn’t already exist). Most Julia code initializes variables by giving them zero values, for eg. `c = zero(Complex{Int})` initializes `c` as a `Complex` variable and gives it a `0 + 0im` initial value.

`local x` or `local x::Int` (the second one declares `x` to hold only `Int` values) are useful only in specific scenarios to get around scoping issues. They initialize the variable but don’t give it any value, so you can’t read from the variables declared this way, only assign to them.

---

<div class="post-metadata">

**Author:** ![ChauhanT](https://avatars.discourse-cdn.com/v4/letter/c/f0a364/32.png) [@ChauhanT](https://discourse.julialang.org/u/ChauhanT)\
**Post date:** [September 1, 2022, 7:03pm UTC](https://discourse.julialang.org/t/read-and-scalar-variables/86619/5 "2022-09-01T19:03:22Z")

</div>

Thank you again for the thorough information. Really appreciated!
