Data types specify what kind of data can be stored and manipulated within a program. Here we don't cover types related to time (Time
, Datetime
).
Briefly intro table:
Type | Example |
---|---|
Integer | 34 |
Float | 34.02 |
Boolean | true/false |
String | "Ama string" |
Charlist | 'Erlang' |
Atom | :ok / :error |
List | [40123, false, :ok] |
Tuple | {40, true, "cat"} |
Map | %{name: "Tom", city: "New York"} |
Range | 1...100 |
Regexp | ~r/[0-9]+\.[0-9]*/ |
Table of contents:
- Integer
- Float
- Boolean
- Atom
- String
- Charlist
- Binaries
- Lists and tuples
- Map
- Ranges
- Regexp
Integers
Numbers without fractional part. Same to any other language. Integer
in Elixir can hold any arbitrary integer (so you don't have int32, long and etc.)
1
2
3
Elixir provides an interesting representation of numbers with underscore similar to Ruby. It's more readable for large numbers.
34_453_234_984
# => 34453234984
Float
Computers use a binary system, so they can't natively represent decimal numbers. Some languages have their own solutions like the BigDecimal
type in Java or Rational
in Ruby. Elixir now contains only float and integer.
Because it is a binary representation of the base 10 system, you get inaccurate results when performing mathematical operations with a "big" fractional part.
0.123123127312631872653718290312312312312
# => 0.12312312731263188
If you are interested, you can read more about floating-point math here.
If you need high accuracy calculations, you can use decimal implementation package
Boolean
The Boolean data type can hold only two values: true or false. It is typically used to store values like yes (true) or no (false), on (true) or off (false), etc., as demonstrated below:
ready? = true
failed? = true
done? = true
Atom
Atoms are constants whose values are their name; it's similar to the symbol type in Ruby lang.
Atoms are equal if their symbols are equal.
:no == :no
# => true
:no == :yes
# => false
They are handy in a situation when you want to express the state of operation, the classic ones :ok and :error
True and false are also atoms, watch the example below:
true == :true
# => true
is_atom(false)
# => true
is_boolean(:false)
# => true
Remark ๐
Because atoms are immutable and created globally for all virtual machine, they are very effective.
String
"Dog"
# => "Dog"
"Car"
# => "Car"
A double-quoted Elixir string is actually encoded as UTF-8
, and the bytes of the string are stored as a binary data type. So when you're working with a string, you're actually working with a binary. A binary is a data type that stores a sequence of bytes.
is_binary("Dog")
# => true
Charlist
Character lists are a special kind of list that is used to store characters. A character list literal is a string of text surrounded by single quotes. The primary use of character lists is to communicate with Erlang functions, which use character lists instead of Elixir strings.
'This is a character list'
Binaries
Binaries are sequences of bytes enclosed in << >>
separated with a comma. For example,
<< 65, 68, 75>>
# => "ADK"
is_binary(<< 65, 68, 75>>)
# => true
List and Tuple
First, take a look at lists. Elixir uses square brackets to specify a list of values. Values can be of any type. For example,
[1, "Hello", :an_atom, true]
hd([1, "Hello", :an_atom, true])
# => 1
tl([1, "Hello", :an_atom, true])
# => true
When Elixir sees a list of printable ASCII numbers, Elixir will print that as a charlist (literally a list of characters).
[104, 101, 108, 108, 111]
# => 'hello'
Charlists are quite common when interfacing with existing Erlang code. Whenever you see a value in IEx and you are not quite sure what it is, you can use the i/1 to retrieve information about it:
[104, 101, 108, 108, 111]
# => 'hello'
i 'hello'
Term
'hello'
Data type
List
Description
...
Raw representation
[104, 101, 108, 108, 111]
Reference modules
List
Implemented protocols
Elixir uses curly brackets to define tuples. Like lists, tuples can hold any value.
{ 1, "Hello", :an_atom, true }
So, what's the difference and when to use tuple and when list?
- Lists are actually stored as linked lists, so insertions, deletions are very fast for tail and head.
- Tuples, on the other hand, are stored in a contiguous memory block, which makes accessing them faster and the size of the tuple is also faster. However, updating or adding elements to tuples is expensive because it requires creating a new tuple in memory.
Operation | List | Tuple |
---|---|---|
Insertion/deletion in head | โ | โ |
Insertion/deletion in tail | โ | โ |
Size of collection | โ | โ |
Accessing element in the middle of collection | โ | โ |
Map
Store an unordered collection of key-value pairs. In the next chapters, we'll look more closer to Map.
%{name: "BMV", type: "car"}
Ranges
It's something similar to ruby, but it works only with integers. So, in a nutshell, it's just an increasing or decreasing sequence of integers. Range is enumerable, so you can iterate over it.
1..100
# => 1..100
Remark ๐
Range is a lazy collection; each element in the range is generated as the range is iterated over.
Regexp
Regular expressions are patterns used to match character combinations in strings.
Regex is based on PCRE (Perl Compatible Regular Expressions) and built on top of Erlang's :re
module, say hello to Ruby. More information can be found in the :re
module documentation.
regex = ~r/[0-9]+\.[0-9]*/
Regex.match?(regex, "0")
# => false
Regex.match?(regex, "1230.4653")
# => true
Top comments (3)
I really glad that I find another Elixir developer.
I write an article with case example so beginner can jump straight into elixir coding.
๐ท epsi.bitbucket.io/lambda/2020/11/1...
Glad to hear you. Good job mate ๐
Thank you.