To understand the precedence of operations, you can run the command: `help operators | sort-by precedence -r`.
Presented in descending order of precedence, the article details the operations as follows:
- Parentheses (`()`)
- Exponentiation/Power (`**`)
- Multiply (`*`), Divide (`/`), Integer/Floor Division (`//`), and Modulo (`mod`)
- Add (`+`) and Subtract (`-`)
- Bit shifting (`bit-shl`, `bit-shr`)
- Comparison operations (`==`, `!=`, `<`, `>`, `<=`, `>=`), membership tests (`in`, `not-in`, `starts-with`, `ends-with`), regex matching (`=~`, `!~`), and list appending (`++`)
- Bitwise and (`bit-and`)
- Bitwise xor (`bit-xor`)
- Bitwise or (`bit-or`)
- Logical and (`and`)
- Logical xor (`xor`)
- Logical or (`or`)
- Assignment operations
- Logical not (`not`)
```nu
3 * (1 + 2)
# => 9
```
## Types
Not all operations make sense for all data types.
If you attempt to perform an operation on non-compatible data types, you will be met with an error message that should explain what went wrong:
```nu
"spam" - 1
# => Error: nu::parser::unsupported_operation (link)
# =>
# => × Types mismatched for operation.
# => ╭─[entry #49:1:1]
# => 1 │ "spam" - 1
# => · ───┬── ┬ ┬
# => · │ │ ╰── int
# => · │ ╰── doesn't support these values.
# => · ╰── string
# => ╰────
# => help: Change string or int to be the right types and try again.
```
The rules might sometimes feel a bit strict, but on the other hand there should be less unexpected side effects.
## Regular Expression / string-contains Operators
The `=~` and `!~` operators provide a convenient way to evaluate [regular expressions](https://cheatography.com/davechild/cheat-sheets/regular-expressions/). You don't need to know regular expressions to use them - they're also an easy way to check whether 1 string contains another.
- `string =~ pattern` returns **true** if `string` contains a match for `pattern`, and **false** otherwise.
- `string !~ pattern` returns **false** if `string` contains a match for `pattern`, and **true** otherwise.
For example:
```nu
foobarbaz =~ bar # returns true
foobarbaz !~ bar # returns false
ls | where name =~ ^nu # returns all files whose names start with "nu"
```
Both operators use [the Rust regex crate's `is_match()` function](https://docs.rs/regex/latest/regex/struct.Regex.html#method.is_match).
## Case Sensitivity
Operators are usually case-sensitive when operating on strings. There are a few ways to do case-insensitive work instead:
1. In the regular expression operators, specify the `(?i)` case-insensitive mode modifier:
```nu
"FOO" =~ "foo" # returns false
"FOO" =~ "(?i)foo" # returns true
```
2. Use the [`str contains`](/commands/docs/str_contains.md) command's `--ignore-case` flag:
```nu
"FOO" | str contains --ignore-case "foo"
```
3. Convert strings to lowercase with [`str downcase`](/commands/docs/str_downcase.md) before comparing:
```nu
("FOO" | str downcase) == ("Foo" | str downcase)
```
## Spread operator
Nushell has a spread operator (`...`) for unpacking lists and records. You may be familiar with it
if you've used JavaScript before. Some languages use `*` for their spread/splat operator. It can
expand lists or records in places where multiple values or key-value pairs are expected.
There are three places you can use the spread operator:
- [In list literals](#in-list-literals)
- [In record literals](#in-record-literals)
- [In command calls](#in-command-calls)
### In List literals
Suppose you have multiple lists you want to concatenate together, but you also want to intersperse
some individual values. This can be done with `append` and `prepend`, but the spread
operator can let you do it more easily.
```nu
let dogs = [Spot, Teddy, Tommy]
let cats = ["Mr. Humphrey Montgomery", Kitten]
[
...$dogs
Polly
...($cats | each { |elt| $"($elt) \(cat\)" })
...[Porky Bessie]
...Nemo
]
# => ╭───┬───────────────────────────────╮
# => │ 0 │ Spot │
# => │ 1 │ Teddy │