diff options
author | chriseth <chris@ethereum.org> | 2019-01-08 07:05:00 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-08 07:05:00 +0800 |
commit | cfa119889224e6d6c9641dafe3099d90de7e4051 (patch) | |
tree | 4f048fe026faa1662391bebc6f7cbfadd82356b8 /docs/contracts | |
parent | cb4e5936fdf1a7d22442c6da08b7ac3a4659f104 (diff) | |
parent | ee5eac4b3edcb36f092b9140323a6e1f8ffa11be (diff) | |
download | dexon-solidity-cfa119889224e6d6c9641dafe3099d90de7e4051.tar.gz dexon-solidity-cfa119889224e6d6c9641dafe3099d90de7e4051.tar.zst dexon-solidity-cfa119889224e6d6c9641dafe3099d90de7e4051.zip |
Merge pull request #5755 from ethereum/docs-split-using-for
[DOCS] Split using for into new file
Diffstat (limited to 'docs/contracts')
-rw-r--r-- | docs/contracts/using-for.rst | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst new file mode 100644 index 00000000..ef456ff4 --- /dev/null +++ b/docs/contracts/using-for.rst @@ -0,0 +1,119 @@ +.. index:: ! using for, library + +.. _using-for: + +********* +Using For +********* + +The directive ``using A for B;`` can be used to attach library +functions (from the library ``A``) to any type (``B``). +These functions will receive the object they are called on +as their first parameter (like the ``self`` variable in Python). + +The effect of ``using A for *;`` is that the functions from +the library ``A`` are attached to *any* type. + +In both situations, *all* functions in the library are attached, +even those where the type of the first parameter does not +match the type of the object. The type is checked at the +point the function is called and function overload +resolution is performed. + +The ``using A for B;`` directive is active only within the current +contract, including within all of its functions, and has no effect +outside of the contract in which it is used. The directive +may only be used inside a contract, not inside any of its functions. + +By including a library, its data types including library functions are +available without having to add further code. + +Let us rewrite the set example from the +:ref:`libraries` in this way:: + + pragma solidity >=0.4.16 <0.6.0; + + // This is the same code as before, just without comments + library Set { + struct Data { mapping(uint => bool) flags; } + + function insert(Data storage self, uint value) + public + returns (bool) + { + if (self.flags[value]) + return false; // already there + self.flags[value] = true; + return true; + } + + function remove(Data storage self, uint value) + public + returns (bool) + { + if (!self.flags[value]) + return false; // not there + self.flags[value] = false; + return true; + } + + function contains(Data storage self, uint value) + public + view + returns (bool) + { + return self.flags[value]; + } + } + + contract C { + using Set for Set.Data; // this is the crucial change + Set.Data knownValues; + + function register(uint value) public { + // Here, all variables of type Set.Data have + // corresponding member functions. + // The following function call is identical to + // `Set.insert(knownValues, value)` + require(knownValues.insert(value)); + } + } + +It is also possible to extend elementary types in that way:: + + pragma solidity >=0.4.16 <0.6.0; + + library Search { + function indexOf(uint[] storage self, uint value) + public + view + returns (uint) + { + for (uint i = 0; i < self.length; i++) + if (self[i] == value) return i; + return uint(-1); + } + } + + contract C { + using Search for uint[]; + uint[] data; + + function append(uint value) public { + data.push(value); + } + + function replace(uint _old, uint _new) public { + // This performs the library function call + uint index = data.indexOf(_old); + if (index == uint(-1)) + data.push(_new); + else + data[index] = _new; + } + } + +Note that all library calls are actual EVM function calls. This means that +if you pass memory or value types, a copy will be performed, even of the +``self`` variable. The only situation where no copy will be performed +is when storage reference variables are used. |