mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 14:32:53 +00:00
tut1.rst makes use of the new ':test:' feature
This commit is contained in:
57
doc/tut1.rst
57
doc/tut1.rst
@@ -30,6 +30,7 @@ The first program
|
||||
We start the tour with a modified "hello world" program:
|
||||
|
||||
.. code-block:: Nim
|
||||
:test: "nim c $1"
|
||||
# This is a comment
|
||||
echo "What's your name? "
|
||||
var name: string = readLine(stdin)
|
||||
@@ -72,6 +73,7 @@ you can leave out the type in the declaration (this is called `local type
|
||||
inference`:idx:). So this will work too:
|
||||
|
||||
.. code-block:: Nim
|
||||
:test: "nim c $1"
|
||||
var name = readLine(stdin)
|
||||
|
||||
Note that this is basically the only form of type inference that exists in
|
||||
@@ -116,6 +118,7 @@ Comments start anywhere outside a string or character literal with the
|
||||
hash character ``#``. Documentation comments start with ``##``:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
# A comment.
|
||||
|
||||
var myVariable: int ## a documentation comment
|
||||
@@ -129,6 +132,7 @@ Multiline comments are started with ``#[`` and terminated with ``]#``. Multilin
|
||||
comments can also be nested.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
#[
|
||||
You can have any Nim code text commented
|
||||
out inside this with no indentation restrictions.
|
||||
@@ -142,6 +146,7 @@ You can also use the `discard statement <#procedures-discard-statement>`_ togeth
|
||||
literals* to create block comments:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
discard """ You can have any Nim code text commented
|
||||
out inside this with no indentation restrictions.
|
||||
yes("May I ask a pointless question?") """
|
||||
@@ -169,6 +174,7 @@ Indentation can be used after the ``var`` keyword to list a whole section of
|
||||
variables:
|
||||
|
||||
.. code-block::
|
||||
:test: "nim c $1"
|
||||
var
|
||||
x, y: int
|
||||
# a comment can occur here too
|
||||
@@ -186,10 +192,11 @@ to a storage location:
|
||||
x = "xyz" # assigns a new value to `x`
|
||||
|
||||
``=`` is the *assignment operator*. The assignment operator can be
|
||||
overloaded. You can declare multiple variables with a single assignment
|
||||
overloaded. You can declare multiple variables with a single assignment
|
||||
statement and all the variables will have the same value:
|
||||
|
||||
.. code-block::
|
||||
:test: "nim c $1"
|
||||
var x, y = 3 # assigns 3 to the variables `x` and `y`
|
||||
echo "x ", x # outputs "x 3"
|
||||
echo "y ", y # outputs "y 3"
|
||||
@@ -212,12 +219,14 @@ cannot change. The compiler must be able to evaluate the expression in a
|
||||
constant declaration at compile time:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
const x = "abc" # the constant x contains the string "abc"
|
||||
|
||||
Indentation can be used after the ``const`` keyword to list a whole section of
|
||||
constants:
|
||||
|
||||
.. code-block::
|
||||
:test: "nim c $1"
|
||||
const
|
||||
x = 1
|
||||
# a comment can occur here too
|
||||
@@ -243,6 +252,7 @@ and put it into a data section":
|
||||
const input = readLine(stdin) # Error: constant expression expected
|
||||
|
||||
.. code-block::
|
||||
:test: "nim c $1"
|
||||
let input = readLine(stdin) # works
|
||||
|
||||
|
||||
@@ -260,6 +270,7 @@ If statement
|
||||
The if statement is one way to branch the control flow:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
let name = readLine(stdin)
|
||||
if name == "":
|
||||
echo "Poor soul, you lost your name?"
|
||||
@@ -281,6 +292,7 @@ Another way to branch is provided by the case statement. A case statement is
|
||||
a multi-branch:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
let name = readLine(stdin)
|
||||
case name
|
||||
of "":
|
||||
@@ -338,6 +350,7 @@ While statement
|
||||
The while statement is a simple looping construct:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
echo "What's your name? "
|
||||
var name = readLine(stdin)
|
||||
@@ -358,6 +371,7 @@ provides. The example uses the built-in `countup <system.html#countup>`_
|
||||
iterator:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
echo "Counting to ten: "
|
||||
for i in countup(1, 10):
|
||||
echo i
|
||||
@@ -409,6 +423,7 @@ Other useful iterators for collections (like arrays and sequences) are
|
||||
* ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively)
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
for index, item in ["a","b"].pairs:
|
||||
echo item, " at index ", index
|
||||
# => a at index 0
|
||||
@@ -421,6 +436,8 @@ new scope. This means that in the following example, ``x`` is not accessible
|
||||
outside the loop:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
:status: 1
|
||||
while false:
|
||||
var x = "hi"
|
||||
echo x # does not work
|
||||
@@ -430,6 +447,8 @@ are only visible within the block they have been declared. The ``block``
|
||||
statement can be used to open a new block explicitly:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
:status: 1
|
||||
block myblock:
|
||||
var x = "hi"
|
||||
echo x # does not work either
|
||||
@@ -444,6 +463,7 @@ can leave a ``while``, ``for``, or a ``block`` statement. It leaves the
|
||||
innermost construct, unless a label of a block is given:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
block myblock:
|
||||
echo "entering block"
|
||||
while true:
|
||||
@@ -465,6 +485,7 @@ Like in many other programming languages, a ``continue`` statement starts
|
||||
the next iteration immediately:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
while true:
|
||||
let x = readLine(stdin)
|
||||
if x == "": continue
|
||||
@@ -477,6 +498,7 @@ When statement
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
when system.hostOS == "windows":
|
||||
echo "running on Windows!"
|
||||
@@ -549,6 +571,7 @@ an expression is allowed:
|
||||
|
||||
.. code-block:: nim
|
||||
# computes fac(4) at compile time:
|
||||
:test: "nim c $1"
|
||||
const fac4 = (var x = 1; for i in 1..4: x *= i; x)
|
||||
|
||||
|
||||
@@ -561,6 +584,7 @@ is needed. (Some languages call them *methods* or *functions*.) In Nim new
|
||||
procedures are defined with the ``proc`` keyword:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc yes(question: string): bool =
|
||||
echo question, " (y/n)"
|
||||
while true:
|
||||
@@ -597,6 +621,7 @@ automatically at the end of a procedure if there is no ``return`` statement at
|
||||
the exit.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc sumTillNegative(x: varargs[int]): int =
|
||||
for i in x:
|
||||
if i < 0:
|
||||
@@ -624,6 +649,7 @@ to be declared with ``var`` in the procedure body. Shadowing the parameter name
|
||||
is possible, and actually an idiom:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc printSeq(s: seq, nprinted: int = -1) =
|
||||
var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
|
||||
for i in 0 .. <nprinted:
|
||||
@@ -633,6 +659,7 @@ If the procedure needs to modify the argument for the
|
||||
caller, a ``var`` parameter can be used:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc divmod(a, b: int; res, remainder: var int) =
|
||||
res = a div b # integer division
|
||||
remainder = a mod b # integer modulo operation
|
||||
@@ -663,6 +690,7 @@ The return value can be ignored implicitly if the called proc/iterator has
|
||||
been declared with the ``discardable`` pragma:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc p(x, y: int): int {.discardable.} =
|
||||
return x + y
|
||||
|
||||
@@ -772,6 +800,7 @@ The "``" notation can also be used to call an operator just like any other
|
||||
procedure:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
if `==`( `+`(3, 4), 7): echo "True"
|
||||
|
||||
|
||||
@@ -819,6 +848,7 @@ Iterators
|
||||
Let's return to the simple counting example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
echo "Counting to ten: "
|
||||
for i in countup(1, 10):
|
||||
echo i
|
||||
@@ -840,6 +870,7 @@ the only thing left to do is to replace the ``proc`` keyword by ``iterator``
|
||||
and here it is - our first iterator:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
iterator countup(a, b: int): int =
|
||||
var res = a
|
||||
while res <= b:
|
||||
@@ -894,7 +925,8 @@ evaluation. For example:
|
||||
Characters
|
||||
----------
|
||||
The `character type` is called ``char``. Its size is always one byte, so
|
||||
it cannot represent most UTF-8 characters; but it *can* represent one of the bytes that makes up a multi-byte UTF-8 character.
|
||||
it cannot represent most UTF-8 characters; but it *can* represent one of the bytes
|
||||
that makes up a multi-byte UTF-8 character.
|
||||
The reason for this is efficiency: for the overwhelming majority of use-cases,
|
||||
the resulting programs will still handle UTF-8 properly as UTF-8 was specially
|
||||
designed for this.
|
||||
@@ -945,6 +977,7 @@ to specify a non-default integer type:
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
let
|
||||
x = 0 # x is of type ``int``
|
||||
y = 0'i8 # y is of type ``int8``
|
||||
@@ -981,6 +1014,7 @@ Float literals can have a *type suffix* to specify a non-default float
|
||||
type:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
var
|
||||
x = 0.0 # x is of type ``float``
|
||||
y = 0.0'f32 # y is of type ``float32``
|
||||
@@ -1002,6 +1036,7 @@ Conversion between basic types is performed by using the
|
||||
type as a function:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
var
|
||||
x: int32 = 1.int32 # same as calling int32(1)
|
||||
y: int8 = int8('a') # 'a' == 97'i8
|
||||
@@ -1023,6 +1058,7 @@ graphs with cycles. The following example shows that even for basic types
|
||||
there is a difference between the ``$`` and ``repr`` outputs:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
var
|
||||
myBool = true
|
||||
myCharacter = 'n'
|
||||
@@ -1047,6 +1083,7 @@ Advanced types
|
||||
In Nim new types can be defined within a ``type`` statement:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
biggestInt = int64 # biggest integer type that is available
|
||||
biggestFloat = float64 # biggest float type that is available
|
||||
@@ -1063,6 +1100,7 @@ to an integer value internally. The first symbol is represented
|
||||
at runtime by 0, the second by 1 and so on. For example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
type
|
||||
Direction = enum
|
||||
@@ -1087,6 +1125,7 @@ explicitly given is assigned the value of the previous symbol + 1.
|
||||
An explicit ordered enum can have *holes*:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
MyEnum = enum
|
||||
a = 2, b = 4, c = 89
|
||||
@@ -1125,6 +1164,7 @@ A subrange type is a range of values from an integer or enumeration type
|
||||
(the base type). Example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
MySubrange = range[0..5]
|
||||
|
||||
@@ -1155,6 +1195,7 @@ an array has the same type. The array's index type can be any ordinal type.
|
||||
Arrays can be constructed using ``[]``:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
type
|
||||
IntArray = array[0..5, int] # an array that is indexed with 0..5
|
||||
@@ -1177,6 +1218,7 @@ length. `low(a) <system.html#low>`_ returns the lowest valid index for the
|
||||
array `a` and `high(a) <system.html#high>`_ the highest valid index.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
Direction = enum
|
||||
north, east, south, west
|
||||
@@ -1228,6 +1270,7 @@ It is quite common to have arrays start at zero, so there's a shortcut syntax
|
||||
to specify a range from zero to the specified index minus one:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
type
|
||||
IntArray = array[0..5, int] # an array that is indexed with 0..5
|
||||
QuickArray = array[6, int] # an array that is indexed with 0..5
|
||||
@@ -1260,6 +1303,7 @@ A sequence may be passed to an openarray parameter.
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
var
|
||||
x: seq[int] # a reference to a sequence of integers
|
||||
@@ -1282,6 +1326,7 @@ value. Here the ``for`` statement is looping over the results from the
|
||||
<system.html>`_ module. Examples:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
for value in @[3, 4, 5]:
|
||||
echo value
|
||||
# --> 3
|
||||
@@ -1308,6 +1353,7 @@ with a compatible base type can be passed to an openarray parameter, the index
|
||||
type does not matter.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
var
|
||||
fruits: seq[string] # reference to a sequence of strings that is initialized with 'nil'
|
||||
capitals: array[3, string] # array of strings with a fixed size
|
||||
@@ -1337,6 +1383,7 @@ arguments to a procedure. The compiler converts the list of arguments
|
||||
to an array automatically:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc myWriteln(f: File, a: varargs[string]) =
|
||||
for s in items(a):
|
||||
write(f, s)
|
||||
@@ -1351,6 +1398,7 @@ last parameter in the procedure header. It is also possible to perform
|
||||
type conversions in this context:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc myWriteln(f: File, a: varargs[string, `$`]) =
|
||||
for s in items(a):
|
||||
write(f, s)
|
||||
@@ -1374,6 +1422,7 @@ context. A slice is just an object of type Slice which contains two bounds,
|
||||
define operators which accept Slice objects to define ranges.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
var
|
||||
a = "Nim is a progamming language"
|
||||
@@ -1429,6 +1478,7 @@ The assignment operator for tuples copies each component. The notation
|
||||
integer.
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
type
|
||||
Person = tuple[name: string, age: int] # type representing a person:
|
||||
@@ -1474,6 +1524,7 @@ otherwise you will be assigning the same value to all the individual
|
||||
variables! For example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
import os
|
||||
|
||||
@@ -1513,6 +1564,7 @@ tuple/object field operator) and ``[]`` (array/string/sequence index operator)
|
||||
operators perform implicit dereferencing operations for reference types:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
type
|
||||
Node = ref object
|
||||
@@ -1542,6 +1594,7 @@ techniques.
|
||||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
proc echoItem(x: int) = echo x
|
||||
|
||||
proc forEach(action: proc (x: int)) =
|
||||
|
||||
Reference in New Issue
Block a user