Merge pull request #5038 from ethereum/controlStructures1

[DOCS] Control structures 1.
This commit is contained in:
chriseth 2018-09-24 16:15:14 +02:00 committed by GitHub
commit 7552928064
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,8 +14,8 @@ parameters as output.
Input Parameters Input Parameters
---------------- ----------------
The input parameters are declared the same way as variables are. As an The input parameters are declared the same way as variables are.
exception, unused parameters can omit the variable name. The name of unused parameters can be omitted.
For example, suppose we want our contract to For example, suppose we want our contract to
accept one kind of external calls with two integers, we would write accept one kind of external calls with two integers, we would write
something like:: something like::
@ -29,6 +29,9 @@ something like::
} }
} }
Input parameters can be used just as any other local variable
can be used, they can also be assigned to.
Output Parameters Output Parameters
----------------- -----------------
@ -51,24 +54,20 @@ write::
} }
The names of output parameters can be omitted. The names of output parameters can be omitted.
The output values can also be specified using ``return`` statements. The output values can also be specified using ``return`` statements,
The ``return`` statements are also capable of returning multiple which are also capable of :ref:`returning multiple values<multi-return>`.
values, see :ref:`multi-return`. Return parameters can be used as any other local variable and they
Return parameters are initialized to zero; if they are not explicitly are zero-initialized; if they are not explicitly
set, they stay to be zero. set, they stay zero.
Input parameters and output parameters can be used as expressions in
the function body. There, they are also usable in the left-hand side
of assignment.
.. index:: if, else, while, do/while, for, break, continue, return, switch, goto .. index:: if, else, while, do/while, for, break, continue, return, switch, goto
Control Structures Control Structures
=================== ===================
Most of the control structures from JavaScript are available in Solidity Most of the control structures known from curly-braces languages are available in Solidity:
except for ``switch`` and ``goto``. So
there is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, ``? :``, with There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with
the usual semantics known from C or JavaScript. the usual semantics known from C or JavaScript.
Parentheses can *not* be omitted for conditionals, but curly brances can be omitted Parentheses can *not* be omitted for conditionals, but curly brances can be omitted
@ -112,6 +111,9 @@ the effect that the current memory is not cleared, i.e. passing memory reference
to internally-called functions is very efficient. Only functions of the same to internally-called functions is very efficient. Only functions of the same
contract can be called internally. contract can be called internally.
You should still avoid excessive recursion, as every internal function call
uses up at least one stack slot and there are at most 1024 slots available.
External Function Calls External Function Calls
----------------------- -----------------------
@ -143,7 +145,7 @@ You need to use the modifier ``payable`` with the ``info`` function because
otherwise, the ``.value()`` option would not be available. otherwise, the ``.value()`` option would not be available.
.. warning:: .. warning::
Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. So in this case, the function is not called.
Function calls cause exceptions if the called contract does not exist (in the Function calls cause exceptions if the called contract does not exist (in the
sense that the account does not contain code) or if the called contract itself sense that the account does not contain code) or if the called contract itself
@ -167,7 +169,7 @@ throws an exception or goes out of gas.
Named Calls and Anonymous Function Parameters Named Calls and Anonymous Function Parameters
--------------------------------------------- ---------------------------------------------
Function call arguments can also be given by name, in any order, Function call arguments can be given by name, in any order,
if they are enclosed in ``{ }`` as can be seen in the following if they are enclosed in ``{ }`` as can be seen in the following
example. The argument list has to coincide by name with the list of example. The argument list has to coincide by name with the list of
parameters from the function declaration, but can be in arbitrary order. parameters from the function declaration, but can be in arbitrary order.
@ -214,9 +216,9 @@ Those parameters will still be present on the stack, but they are inaccessible.
Creating Contracts via ``new`` Creating Contracts via ``new``
============================== ==============================
A contract can create a new contract using the ``new`` keyword. The full A contract can create other contracts using the ``new`` keyword. The full
code of the contract being created has to be known in advance, so recursive code of the contract being created has to be known when the creating contract
creation-dependencies are not possible. is compiled so recursive creation-dependencies are not possible.
:: ::
@ -244,7 +246,7 @@ creation-dependencies are not possible.
} }
} }
As seen in the example, it is possible to forward Ether while creating As seen in the example, it is possible to send Ether while creating
an instance of ``D`` using the ``.value()`` option, but it is not possible an instance of ``D`` using the ``.value()`` option, but it is not possible
to limit the amount of gas. to limit the amount of gas.
If the creation fails (due to out-of-stack, not enough balance or other problems), If the creation fails (due to out-of-stack, not enough balance or other problems),
@ -269,8 +271,11 @@ Assignment
Destructuring Assignments and Returning Multiple Values Destructuring Assignments and Returning Multiple Values
------------------------------------------------------- -------------------------------------------------------
Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time. Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose number is a constant at compile-time. Those tuples can be used to return multiple values at the same time.
These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general): These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general).
Tuples are not proper types in Solidity, they can only be used to form syntactic
groupings of expressions.
:: ::
@ -294,15 +299,23 @@ These can then either be assigned to newly declared variables or to pre-existing
} }
} }
It is not possible to mix variable declarations and non-declaration assignments,
i.e. the following is not valid: ``(x, uint y) = (1, 2);``
.. note:: .. note::
Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either
filling up on the left or on the right side (which ever was empty). This is filling up on the left or on the right side (which ever was empty). This is
now disallowed, so both sides have to have the same number of components. now disallowed, so both sides have to have the same number of components.
.. warning::
Be careful when assigning to multiple variables at the same time when
reference types are involved, because it could lead to unexpected
copying behaviour.
Complications for Arrays and Structs Complications for Arrays and Structs
------------------------------------ ------------------------------------
The semantics of assignment are a bit more complicated for non-value types like arrays and structs. The semantics of assignments are a bit more complicated for non-value types like arrays and structs.
Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including ``bytes`` and ``string``) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state. Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including ``bytes`` and ``string``) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state.
.. index:: ! scoping, declarations, default value .. index:: ! scoping, declarations, default value
@ -320,11 +333,11 @@ and ``string``, the default value is an empty array or string.
Scoping in Solidity follows the widespread scoping rules of C99 Scoping in Solidity follows the widespread scoping rules of C99
(and many other languages): Variables are visible from the point right after their declaration (and many other languages): Variables are visible from the point right after their declaration
until the end of a ``{ }``-block. As an exception to this rule, variables declared in the until the end of the smallest ``{ }``-block that contains the declaration. As an exception to this rule, variables declared in the
initialization part of a for-loop are only visible until the end of the for-loop. initialization part of a for-loop are only visible until the end of the for-loop.
Variables and other items declared outside of a code block, for example functions, contracts, Variables and other items declared outside of a code block, for example functions, contracts,
user-defined types, etc., do not change their scoping behaviour. This means you can user-defined types, etc., are visible even before they were declared. This means you can
use state variables before they are declared and call functions recursively. use state variables before they are declared and call functions recursively.
As a consequence, the following examples will compile without warnings, since As a consequence, the following examples will compile without warnings, since
@ -368,7 +381,7 @@ In any case, you will get a warning about the outer variable being shadowed.
.. warning:: .. warning::
Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope
for the entire function, regardless where it was declared. Note that this is a breaking change. The following example shows a code snippet that used for the entire function, regardless where it was declared. The following example shows a code snippet that used
to compile but leads to an error starting from version 0.5.0. to compile but leads to an error starting from version 0.5.0.
:: ::