1593017460
Python is an older language and it has many versions. In this video I go over some of the versions of Python, from Python 2.7 to Python 3.10. More importantly, I help you to understand how think about Python versions in your actual programming career.
#python #versions
1653475560
msgpack.php
A pure PHP implementation of the MessagePack serialization format.
The recommended way to install the library is through Composer:
composer require rybakit/msgpack
To pack values you can either use an instance of a Packer
:
$packer = new Packer();
$packed = $packer->pack($value);
or call a static method on the MessagePack
class:
$packed = MessagePack::pack($value);
In the examples above, the method pack
automatically packs a value depending on its type. However, not all PHP types can be uniquely translated to MessagePack types. For example, the MessagePack format defines map
and array
types, which are represented by a single array
type in PHP. By default, the packer will pack a PHP array as a MessagePack array if it has sequential numeric keys, starting from 0
and as a MessagePack map otherwise:
$mpArr1 = $packer->pack([1, 2]); // MP array [1, 2]
$mpArr2 = $packer->pack([0 => 1, 1 => 2]); // MP array [1, 2]
$mpMap1 = $packer->pack([0 => 1, 2 => 3]); // MP map {0: 1, 2: 3}
$mpMap2 = $packer->pack([1 => 2, 2 => 3]); // MP map {1: 2, 2: 3}
$mpMap3 = $packer->pack(['a' => 1, 'b' => 2]); // MP map {a: 1, b: 2}
However, sometimes you need to pack a sequential array as a MessagePack map. To do this, use the packMap
method:
$mpMap = $packer->packMap([1, 2]); // {0: 1, 1: 2}
Here is a list of type-specific packing methods:
$packer->packNil(); // MP nil
$packer->packBool(true); // MP bool
$packer->packInt(42); // MP int
$packer->packFloat(M_PI); // MP float (32 or 64)
$packer->packFloat32(M_PI); // MP float 32
$packer->packFloat64(M_PI); // MP float 64
$packer->packStr('foo'); // MP str
$packer->packBin("\x80"); // MP bin
$packer->packArray([1, 2]); // MP array
$packer->packMap(['a' => 1]); // MP map
$packer->packExt(1, "\xaa"); // MP ext
Check the "Custom types" section below on how to pack custom types.
The Packer
object supports a number of bitmask-based options for fine-tuning the packing process (defaults are in bold):
Name | Description |
---|---|
FORCE_STR | Forces PHP strings to be packed as MessagePack UTF-8 strings |
FORCE_BIN | Forces PHP strings to be packed as MessagePack binary data |
DETECT_STR_BIN | Detects MessagePack str/bin type automatically |
FORCE_ARR | Forces PHP arrays to be packed as MessagePack arrays |
FORCE_MAP | Forces PHP arrays to be packed as MessagePack maps |
DETECT_ARR_MAP | Detects MessagePack array/map type automatically |
FORCE_FLOAT32 | Forces PHP floats to be packed as 32-bits MessagePack floats |
FORCE_FLOAT64 | Forces PHP floats to be packed as 64-bits MessagePack floats |
The type detection mode (
DETECT_STR_BIN
/DETECT_ARR_MAP
) adds some overhead which can be noticed when you pack large (16- and 32-bit) arrays or strings. However, if you know the value type in advance (for example, you only work with UTF-8 strings or/and associative arrays), you can eliminate this overhead by forcing the packer to use the appropriate type, which will save it from running the auto-detection routine. Another option is to explicitly specify the value type. The library provides 2 auxiliary classes for this,Map
andBin
. Check the "Custom types" section below for details.
Examples:
// detect str/bin type and pack PHP 64-bit floats (doubles) to MP 32-bit floats
$packer = new Packer(PackOptions::DETECT_STR_BIN | PackOptions::FORCE_FLOAT32);
// these will throw MessagePack\Exception\InvalidOptionException
$packer = new Packer(PackOptions::FORCE_STR | PackOptions::FORCE_BIN);
$packer = new Packer(PackOptions::FORCE_FLOAT32 | PackOptions::FORCE_FLOAT64);
To unpack data you can either use an instance of a BufferUnpacker
:
$unpacker = new BufferUnpacker();
$unpacker->reset($packed);
$value = $unpacker->unpack();
or call a static method on the MessagePack
class:
$value = MessagePack::unpack($packed);
If the packed data is received in chunks (e.g. when reading from a stream), use the tryUnpack
method, which attempts to unpack data and returns an array of unpacked messages (if any) instead of throwing an InsufficientDataException
:
while ($chunk = ...) {
$unpacker->append($chunk);
if ($messages = $unpacker->tryUnpack()) {
return $messages;
}
}
If you want to unpack from a specific position in a buffer, use seek
:
$unpacker->seek(42); // set position equal to 42 bytes
$unpacker->seek(-8); // set position to 8 bytes before the end of the buffer
To skip bytes from the current position, use skip
:
$unpacker->skip(10); // set position to 10 bytes ahead of the current position
To get the number of remaining (unread) bytes in the buffer:
$unreadBytesCount = $unpacker->getRemainingCount();
To check whether the buffer has unread data:
$hasUnreadBytes = $unpacker->hasRemaining();
If needed, you can remove already read data from the buffer by calling:
$releasedBytesCount = $unpacker->release();
With the read
method you can read raw (packed) data:
$packedData = $unpacker->read(2); // read 2 bytes
Besides the above methods BufferUnpacker
provides type-specific unpacking methods, namely:
$unpacker->unpackNil(); // PHP null
$unpacker->unpackBool(); // PHP bool
$unpacker->unpackInt(); // PHP int
$unpacker->unpackFloat(); // PHP float
$unpacker->unpackStr(); // PHP UTF-8 string
$unpacker->unpackBin(); // PHP binary string
$unpacker->unpackArray(); // PHP sequential array
$unpacker->unpackMap(); // PHP associative array
$unpacker->unpackExt(); // PHP MessagePack\Type\Ext object
The BufferUnpacker
object supports a number of bitmask-based options for fine-tuning the unpacking process (defaults are in bold):
Name | Description |
---|---|
BIGINT_AS_STR | Converts overflowed integers to strings [1] |
BIGINT_AS_GMP | Converts overflowed integers to GMP objects [2] |
BIGINT_AS_DEC | Converts overflowed integers to Decimal\Decimal objects [3] |
1. The binary MessagePack format has unsigned 64-bit as its largest integer data type, but PHP does not support such integers, which means that an overflow can occur during unpacking.
2. Make sure the GMP extension is enabled.
3. Make sure the Decimal extension is enabled.
Examples:
$packedUint64 = "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff";
$unpacker = new BufferUnpacker($packedUint64);
var_dump($unpacker->unpack()); // string(20) "18446744073709551615"
$unpacker = new BufferUnpacker($packedUint64, UnpackOptions::BIGINT_AS_GMP);
var_dump($unpacker->unpack()); // object(GMP) {...}
$unpacker = new BufferUnpacker($packedUint64, UnpackOptions::BIGINT_AS_DEC);
var_dump($unpacker->unpack()); // object(Decimal\Decimal) {...}
In addition to the basic types, the library provides functionality to serialize and deserialize arbitrary types. This can be done in several ways, depending on your use case. Let's take a look at them.
If you need to serialize an instance of one of your classes into one of the basic MessagePack types, the best way to do this is to implement the CanBePacked interface in the class. A good example of such a class is the Map
type class that comes with the library. This type is useful when you want to explicitly specify that a given PHP array should be packed as a MessagePack map without triggering an automatic type detection routine:
$packer = new Packer();
$packedMap = $packer->pack(new Map([1, 2, 3]));
$packedArray = $packer->pack([1, 2, 3]);
More type examples can be found in the src/Type directory.
As with type objects, type transformers are only responsible for serializing values. They should be used when you need to serialize a value that does not implement the CanBePacked interface. Examples of such values could be instances of built-in or third-party classes that you don't own, or non-objects such as resources.
A transformer class must implement the CanPack interface. To use a transformer, it must first be registered in the packer. Here is an example of how to serialize PHP streams into the MessagePack bin
format type using one of the supplied transformers, StreamTransformer
:
$packer = new Packer(null, [new StreamTransformer()]);
$packedBin = $packer->pack(fopen('/path/to/file', 'r+'));
More type transformer examples can be found in the src/TypeTransformer directory.
In contrast to the cases described above, extensions are intended to handle extension types and are responsible for both serialization and deserialization of values (types).
An extension class must implement the Extension interface. To use an extension, it must first be registered in the packer and the unpacker.
The MessagePack specification divides extension types into two groups: predefined and application-specific. Currently, there is only one predefined type in the specification, Timestamp.
Timestamp
The Timestamp extension type is a predefined type. Support for this type in the library is done through the TimestampExtension
class. This class is responsible for handling Timestamp
objects, which represent the number of seconds and optional adjustment in nanoseconds:
$timestampExtension = new TimestampExtension();
$packer = new Packer();
$packer = $packer->extendWith($timestampExtension);
$unpacker = new BufferUnpacker();
$unpacker = $unpacker->extendWith($timestampExtension);
$packedTimestamp = $packer->pack(Timestamp::now());
$timestamp = $unpacker->reset($packedTimestamp)->unpack();
$seconds = $timestamp->getSeconds();
$nanoseconds = $timestamp->getNanoseconds();
When using the MessagePack
class, the Timestamp extension is already registered:
$packedTimestamp = MessagePack::pack(Timestamp::now());
$timestamp = MessagePack::unpack($packedTimestamp);
Application-specific extensions
In addition, the format can be extended with your own types. For example, to make the built-in PHP DateTime
objects first-class citizens in your code, you can create a corresponding extension, as shown in the example. Please note, that custom extensions have to be registered with a unique extension ID (an integer from 0
to 127
).
More extension examples can be found in the examples/MessagePack directory.
To learn more about how extension types can be useful, check out this article.
If an error occurs during packing/unpacking, a PackingFailedException
or an UnpackingFailedException
will be thrown, respectively. In addition, an InsufficientDataException
can be thrown during unpacking.
An InvalidOptionException
will be thrown in case an invalid option (or a combination of mutually exclusive options) is used.
Run tests as follows:
vendor/bin/phpunit
Also, if you already have Docker installed, you can run the tests in a docker container. First, create a container:
./dockerfile.sh | docker build -t msgpack -
The command above will create a container named msgpack
with PHP 8.1 runtime. You may change the default runtime by defining the PHP_IMAGE
environment variable:
PHP_IMAGE='php:8.0-cli' ./dockerfile.sh | docker build -t msgpack -
See a list of various images here.
Then run the unit tests:
docker run --rm -v $PWD:/msgpack -w /msgpack msgpack
To ensure that the unpacking works correctly with malformed/semi-malformed data, you can use a testing technique called Fuzzing. The library ships with a help file (target) for PHP-Fuzzer and can be used as follows:
php-fuzzer fuzz tests/fuzz_buffer_unpacker.php
To check performance, run:
php -n -dzend_extension=opcache.so \
-dpcre.jit=1 -dopcache.enable=1 -dopcache.enable_cli=1 \
tests/bench.php
Example output
Filter: MessagePack\Tests\Perf\Filter\ListFilter
Rounds: 3
Iterations: 100000
=============================================
Test/Target Packer BufferUnpacker
---------------------------------------------
nil .................. 0.0030 ........ 0.0139
false ................ 0.0037 ........ 0.0144
true ................. 0.0040 ........ 0.0137
7-bit uint #1 ........ 0.0052 ........ 0.0120
7-bit uint #2 ........ 0.0059 ........ 0.0114
7-bit uint #3 ........ 0.0061 ........ 0.0119
5-bit sint #1 ........ 0.0067 ........ 0.0126
5-bit sint #2 ........ 0.0064 ........ 0.0132
5-bit sint #3 ........ 0.0066 ........ 0.0135
8-bit uint #1 ........ 0.0078 ........ 0.0200
8-bit uint #2 ........ 0.0077 ........ 0.0212
8-bit uint #3 ........ 0.0086 ........ 0.0203
16-bit uint #1 ....... 0.0111 ........ 0.0271
16-bit uint #2 ....... 0.0115 ........ 0.0260
16-bit uint #3 ....... 0.0103 ........ 0.0273
32-bit uint #1 ....... 0.0116 ........ 0.0326
32-bit uint #2 ....... 0.0118 ........ 0.0332
32-bit uint #3 ....... 0.0127 ........ 0.0325
64-bit uint #1 ....... 0.0140 ........ 0.0277
64-bit uint #2 ....... 0.0134 ........ 0.0294
64-bit uint #3 ....... 0.0134 ........ 0.0281
8-bit int #1 ......... 0.0086 ........ 0.0241
8-bit int #2 ......... 0.0089 ........ 0.0225
8-bit int #3 ......... 0.0085 ........ 0.0229
16-bit int #1 ........ 0.0118 ........ 0.0280
16-bit int #2 ........ 0.0121 ........ 0.0270
16-bit int #3 ........ 0.0109 ........ 0.0274
32-bit int #1 ........ 0.0128 ........ 0.0346
32-bit int #2 ........ 0.0118 ........ 0.0339
32-bit int #3 ........ 0.0135 ........ 0.0368
64-bit int #1 ........ 0.0138 ........ 0.0276
64-bit int #2 ........ 0.0132 ........ 0.0286
64-bit int #3 ........ 0.0137 ........ 0.0274
64-bit int #4 ........ 0.0180 ........ 0.0285
64-bit float #1 ...... 0.0134 ........ 0.0284
64-bit float #2 ...... 0.0125 ........ 0.0275
64-bit float #3 ...... 0.0126 ........ 0.0283
fix string #1 ........ 0.0035 ........ 0.0133
fix string #2 ........ 0.0094 ........ 0.0216
fix string #3 ........ 0.0094 ........ 0.0222
fix string #4 ........ 0.0091 ........ 0.0241
8-bit string #1 ...... 0.0122 ........ 0.0301
8-bit string #2 ...... 0.0118 ........ 0.0304
8-bit string #3 ...... 0.0119 ........ 0.0315
16-bit string #1 ..... 0.0150 ........ 0.0388
16-bit string #2 ..... 0.1545 ........ 0.1665
32-bit string ........ 0.1570 ........ 0.1756
wide char string #1 .. 0.0091 ........ 0.0236
wide char string #2 .. 0.0122 ........ 0.0313
8-bit binary #1 ...... 0.0100 ........ 0.0302
8-bit binary #2 ...... 0.0123 ........ 0.0324
8-bit binary #3 ...... 0.0126 ........ 0.0327
16-bit binary ........ 0.0168 ........ 0.0372
32-bit binary ........ 0.1588 ........ 0.1754
fix array #1 ......... 0.0042 ........ 0.0131
fix array #2 ......... 0.0294 ........ 0.0367
fix array #3 ......... 0.0412 ........ 0.0472
16-bit array #1 ...... 0.1378 ........ 0.1596
16-bit array #2 ........... S ............. S
32-bit array .............. S ............. S
complex array ........ 0.1865 ........ 0.2283
fix map #1 ........... 0.0725 ........ 0.1048
fix map #2 ........... 0.0319 ........ 0.0405
fix map #3 ........... 0.0356 ........ 0.0665
fix map #4 ........... 0.0465 ........ 0.0497
16-bit map #1 ........ 0.2540 ........ 0.3028
16-bit map #2 ............. S ............. S
32-bit map ................ S ............. S
complex map .......... 0.2372 ........ 0.2710
fixext 1 ............. 0.0283 ........ 0.0358
fixext 2 ............. 0.0291 ........ 0.0371
fixext 4 ............. 0.0302 ........ 0.0355
fixext 8 ............. 0.0288 ........ 0.0384
fixext 16 ............ 0.0293 ........ 0.0359
8-bit ext ............ 0.0302 ........ 0.0439
16-bit ext ........... 0.0334 ........ 0.0499
32-bit ext ........... 0.1845 ........ 0.1888
32-bit timestamp #1 .. 0.0337 ........ 0.0547
32-bit timestamp #2 .. 0.0335 ........ 0.0560
64-bit timestamp #1 .. 0.0371 ........ 0.0575
64-bit timestamp #2 .. 0.0374 ........ 0.0542
64-bit timestamp #3 .. 0.0356 ........ 0.0533
96-bit timestamp #1 .. 0.0362 ........ 0.0699
96-bit timestamp #2 .. 0.0381 ........ 0.0701
96-bit timestamp #3 .. 0.0367 ........ 0.0687
=============================================
Total 2.7618 4.0820
Skipped 4 4
Failed 0 0
Ignored 0 0
With JIT:
php -n -dzend_extension=opcache.so \
-dpcre.jit=1 -dopcache.jit_buffer_size=64M -dopcache.jit=tracing -dopcache.enable=1 -dopcache.enable_cli=1 \
tests/bench.php
Example output
Filter: MessagePack\Tests\Perf\Filter\ListFilter
Rounds: 3
Iterations: 100000
=============================================
Test/Target Packer BufferUnpacker
---------------------------------------------
nil .................. 0.0005 ........ 0.0054
false ................ 0.0004 ........ 0.0059
true ................. 0.0004 ........ 0.0059
7-bit uint #1 ........ 0.0010 ........ 0.0047
7-bit uint #2 ........ 0.0010 ........ 0.0046
7-bit uint #3 ........ 0.0010 ........ 0.0046
5-bit sint #1 ........ 0.0025 ........ 0.0046
5-bit sint #2 ........ 0.0023 ........ 0.0046
5-bit sint #3 ........ 0.0024 ........ 0.0045
8-bit uint #1 ........ 0.0043 ........ 0.0081
8-bit uint #2 ........ 0.0043 ........ 0.0079
8-bit uint #3 ........ 0.0041 ........ 0.0080
16-bit uint #1 ....... 0.0064 ........ 0.0095
16-bit uint #2 ....... 0.0064 ........ 0.0091
16-bit uint #3 ....... 0.0064 ........ 0.0094
32-bit uint #1 ....... 0.0085 ........ 0.0114
32-bit uint #2 ....... 0.0077 ........ 0.0122
32-bit uint #3 ....... 0.0077 ........ 0.0120
64-bit uint #1 ....... 0.0085 ........ 0.0159
64-bit uint #2 ....... 0.0086 ........ 0.0157
64-bit uint #3 ....... 0.0086 ........ 0.0158
8-bit int #1 ......... 0.0042 ........ 0.0080
8-bit int #2 ......... 0.0042 ........ 0.0080
8-bit int #3 ......... 0.0042 ........ 0.0081
16-bit int #1 ........ 0.0065 ........ 0.0095
16-bit int #2 ........ 0.0065 ........ 0.0090
16-bit int #3 ........ 0.0056 ........ 0.0085
32-bit int #1 ........ 0.0067 ........ 0.0107
32-bit int #2 ........ 0.0066 ........ 0.0106
32-bit int #3 ........ 0.0063 ........ 0.0104
64-bit int #1 ........ 0.0072 ........ 0.0162
64-bit int #2 ........ 0.0073 ........ 0.0174
64-bit int #3 ........ 0.0072 ........ 0.0164
64-bit int #4 ........ 0.0077 ........ 0.0161
64-bit float #1 ...... 0.0053 ........ 0.0135
64-bit float #2 ...... 0.0053 ........ 0.0135
64-bit float #3 ...... 0.0052 ........ 0.0135
fix string #1 ....... -0.0002 ........ 0.0044
fix string #2 ........ 0.0035 ........ 0.0067
fix string #3 ........ 0.0035 ........ 0.0077
fix string #4 ........ 0.0033 ........ 0.0078
8-bit string #1 ...... 0.0059 ........ 0.0110
8-bit string #2 ...... 0.0063 ........ 0.0121
8-bit string #3 ...... 0.0064 ........ 0.0124
16-bit string #1 ..... 0.0099 ........ 0.0146
16-bit string #2 ..... 0.1522 ........ 0.1474
32-bit string ........ 0.1511 ........ 0.1483
wide char string #1 .. 0.0039 ........ 0.0084
wide char string #2 .. 0.0073 ........ 0.0123
8-bit binary #1 ...... 0.0040 ........ 0.0112
8-bit binary #2 ...... 0.0075 ........ 0.0123
8-bit binary #3 ...... 0.0077 ........ 0.0129
16-bit binary ........ 0.0096 ........ 0.0145
32-bit binary ........ 0.1535 ........ 0.1479
fix array #1 ......... 0.0008 ........ 0.0061
fix array #2 ......... 0.0121 ........ 0.0165
fix array #3 ......... 0.0193 ........ 0.0222
16-bit array #1 ...... 0.0607 ........ 0.0479
16-bit array #2 ........... S ............. S
32-bit array .............. S ............. S
complex array ........ 0.0749 ........ 0.0824
fix map #1 ........... 0.0329 ........ 0.0431
fix map #2 ........... 0.0161 ........ 0.0189
fix map #3 ........... 0.0205 ........ 0.0262
fix map #4 ........... 0.0252 ........ 0.0205
16-bit map #1 ........ 0.1016 ........ 0.0927
16-bit map #2 ............. S ............. S
32-bit map ................ S ............. S
complex map .......... 0.1096 ........ 0.1030
fixext 1 ............. 0.0157 ........ 0.0161
fixext 2 ............. 0.0175 ........ 0.0183
fixext 4 ............. 0.0156 ........ 0.0185
fixext 8 ............. 0.0163 ........ 0.0184
fixext 16 ............ 0.0164 ........ 0.0182
8-bit ext ............ 0.0158 ........ 0.0207
16-bit ext ........... 0.0203 ........ 0.0219
32-bit ext ........... 0.1614 ........ 0.1539
32-bit timestamp #1 .. 0.0195 ........ 0.0249
32-bit timestamp #2 .. 0.0188 ........ 0.0260
64-bit timestamp #1 .. 0.0207 ........ 0.0281
64-bit timestamp #2 .. 0.0212 ........ 0.0291
64-bit timestamp #3 .. 0.0207 ........ 0.0295
96-bit timestamp #1 .. 0.0222 ........ 0.0358
96-bit timestamp #2 .. 0.0228 ........ 0.0353
96-bit timestamp #3 .. 0.0210 ........ 0.0319
=============================================
Total 1.6432 1.9674
Skipped 4 4
Failed 0 0
Ignored 0 0
You may change default benchmark settings by defining the following environment variables:
Name | Default |
---|---|
MP_BENCH_TARGETS | pure_p,pure_u , see a list of available targets |
MP_BENCH_ITERATIONS | 100_000 |
MP_BENCH_DURATION | not set |
MP_BENCH_ROUNDS | 3 |
MP_BENCH_TESTS | -@slow , see a list of available tests |
For example:
export MP_BENCH_TARGETS=pure_p
export MP_BENCH_ITERATIONS=1000000
export MP_BENCH_ROUNDS=5
# a comma separated list of test names
export MP_BENCH_TESTS='complex array, complex map'
# or a group name
# export MP_BENCH_TESTS='-@slow' // @pecl_comp
# or a regexp
# export MP_BENCH_TESTS='/complex (array|map)/'
Another example, benchmarking both the library and the PECL extension:
MP_BENCH_TARGETS=pure_p,pure_u,pecl_p,pecl_u \
php -n -dextension=msgpack.so -dzend_extension=opcache.so \
-dpcre.jit=1 -dopcache.enable=1 -dopcache.enable_cli=1 \
tests/bench.php
Example output
Filter: MessagePack\Tests\Perf\Filter\ListFilter
Rounds: 3
Iterations: 100000
===========================================================================
Test/Target Packer BufferUnpacker msgpack_pack msgpack_unpack
---------------------------------------------------------------------------
nil .................. 0.0031 ........ 0.0141 ...... 0.0055 ........ 0.0064
false ................ 0.0039 ........ 0.0154 ...... 0.0056 ........ 0.0053
true ................. 0.0038 ........ 0.0139 ...... 0.0056 ........ 0.0044
7-bit uint #1 ........ 0.0061 ........ 0.0110 ...... 0.0059 ........ 0.0046
7-bit uint #2 ........ 0.0065 ........ 0.0119 ...... 0.0042 ........ 0.0029
7-bit uint #3 ........ 0.0054 ........ 0.0117 ...... 0.0045 ........ 0.0025
5-bit sint #1 ........ 0.0047 ........ 0.0103 ...... 0.0038 ........ 0.0022
5-bit sint #2 ........ 0.0048 ........ 0.0117 ...... 0.0038 ........ 0.0022
5-bit sint #3 ........ 0.0046 ........ 0.0102 ...... 0.0038 ........ 0.0023
8-bit uint #1 ........ 0.0063 ........ 0.0174 ...... 0.0039 ........ 0.0031
8-bit uint #2 ........ 0.0063 ........ 0.0167 ...... 0.0040 ........ 0.0029
8-bit uint #3 ........ 0.0063 ........ 0.0168 ...... 0.0039 ........ 0.0030
16-bit uint #1 ....... 0.0092 ........ 0.0222 ...... 0.0049 ........ 0.0030
16-bit uint #2 ....... 0.0096 ........ 0.0227 ...... 0.0042 ........ 0.0046
16-bit uint #3 ....... 0.0123 ........ 0.0274 ...... 0.0059 ........ 0.0051
32-bit uint #1 ....... 0.0136 ........ 0.0331 ...... 0.0060 ........ 0.0048
32-bit uint #2 ....... 0.0130 ........ 0.0336 ...... 0.0070 ........ 0.0048
32-bit uint #3 ....... 0.0127 ........ 0.0329 ...... 0.0051 ........ 0.0048
64-bit uint #1 ....... 0.0126 ........ 0.0268 ...... 0.0055 ........ 0.0049
64-bit uint #2 ....... 0.0135 ........ 0.0281 ...... 0.0052 ........ 0.0046
64-bit uint #3 ....... 0.0131 ........ 0.0274 ...... 0.0069 ........ 0.0044
8-bit int #1 ......... 0.0077 ........ 0.0236 ...... 0.0058 ........ 0.0044
8-bit int #2 ......... 0.0087 ........ 0.0244 ...... 0.0058 ........ 0.0048
8-bit int #3 ......... 0.0084 ........ 0.0241 ...... 0.0055 ........ 0.0049
16-bit int #1 ........ 0.0112 ........ 0.0271 ...... 0.0048 ........ 0.0045
16-bit int #2 ........ 0.0124 ........ 0.0292 ...... 0.0057 ........ 0.0049
16-bit int #3 ........ 0.0118 ........ 0.0270 ...... 0.0058 ........ 0.0050
32-bit int #1 ........ 0.0137 ........ 0.0366 ...... 0.0058 ........ 0.0051
32-bit int #2 ........ 0.0133 ........ 0.0366 ...... 0.0056 ........ 0.0049
32-bit int #3 ........ 0.0129 ........ 0.0350 ...... 0.0052 ........ 0.0048
64-bit int #1 ........ 0.0145 ........ 0.0254 ...... 0.0034 ........ 0.0025
64-bit int #2 ........ 0.0097 ........ 0.0214 ...... 0.0034 ........ 0.0025
64-bit int #3 ........ 0.0096 ........ 0.0287 ...... 0.0059 ........ 0.0050
64-bit int #4 ........ 0.0143 ........ 0.0277 ...... 0.0059 ........ 0.0046
64-bit float #1 ...... 0.0134 ........ 0.0281 ...... 0.0057 ........ 0.0052
64-bit float #2 ...... 0.0141 ........ 0.0281 ...... 0.0057 ........ 0.0050
64-bit float #3 ...... 0.0144 ........ 0.0282 ...... 0.0057 ........ 0.0050
fix string #1 ........ 0.0036 ........ 0.0143 ...... 0.0066 ........ 0.0053
fix string #2 ........ 0.0107 ........ 0.0222 ...... 0.0065 ........ 0.0068
fix string #3 ........ 0.0116 ........ 0.0245 ...... 0.0063 ........ 0.0069
fix string #4 ........ 0.0105 ........ 0.0253 ...... 0.0083 ........ 0.0077
8-bit string #1 ...... 0.0126 ........ 0.0318 ...... 0.0075 ........ 0.0088
8-bit string #2 ...... 0.0121 ........ 0.0295 ...... 0.0076 ........ 0.0086
8-bit string #3 ...... 0.0125 ........ 0.0293 ...... 0.0130 ........ 0.0093
16-bit string #1 ..... 0.0159 ........ 0.0368 ...... 0.0117 ........ 0.0086
16-bit string #2 ..... 0.1547 ........ 0.1686 ...... 0.1516 ........ 0.1373
32-bit string ........ 0.1558 ........ 0.1729 ...... 0.1511 ........ 0.1396
wide char string #1 .. 0.0098 ........ 0.0237 ...... 0.0066 ........ 0.0065
wide char string #2 .. 0.0128 ........ 0.0291 ...... 0.0061 ........ 0.0082
8-bit binary #1 ........... I ............. I ........... F ............. I
8-bit binary #2 ........... I ............. I ........... F ............. I
8-bit binary #3 ........... I ............. I ........... F ............. I
16-bit binary ............. I ............. I ........... F ............. I
32-bit binary ............. I ............. I ........... F ............. I
fix array #1 ......... 0.0040 ........ 0.0129 ...... 0.0120 ........ 0.0058
fix array #2 ......... 0.0279 ........ 0.0390 ...... 0.0143 ........ 0.0165
fix array #3 ......... 0.0415 ........ 0.0463 ...... 0.0162 ........ 0.0187
16-bit array #1 ...... 0.1349 ........ 0.1628 ...... 0.0334 ........ 0.0341
16-bit array #2 ........... S ............. S ........... S ............. S
32-bit array .............. S ............. S ........... S ............. S
complex array ............. I ............. I ........... F ............. F
fix map #1 ................ I ............. I ........... F ............. I
fix map #2 ........... 0.0345 ........ 0.0391 ...... 0.0143 ........ 0.0168
fix map #3 ................ I ............. I ........... F ............. I
fix map #4 ........... 0.0459 ........ 0.0473 ...... 0.0151 ........ 0.0163
16-bit map #1 ........ 0.2518 ........ 0.2962 ...... 0.0400 ........ 0.0490
16-bit map #2 ............. S ............. S ........... S ............. S
32-bit map ................ S ............. S ........... S ............. S
complex map .......... 0.2380 ........ 0.2682 ...... 0.0545 ........ 0.0579
fixext 1 .................. I ............. I ........... F ............. F
fixext 2 .................. I ............. I ........... F ............. F
fixext 4 .................. I ............. I ........... F ............. F
fixext 8 .................. I ............. I ........... F ............. F
fixext 16 ................. I ............. I ........... F ............. F
8-bit ext ................. I ............. I ........... F ............. F
16-bit ext ................ I ............. I ........... F ............. F
32-bit ext ................ I ............. I ........... F ............. F
32-bit timestamp #1 ....... I ............. I ........... F ............. F
32-bit timestamp #2 ....... I ............. I ........... F ............. F
64-bit timestamp #1 ....... I ............. I ........... F ............. F
64-bit timestamp #2 ....... I ............. I ........... F ............. F
64-bit timestamp #3 ....... I ............. I ........... F ............. F
96-bit timestamp #1 ....... I ............. I ........... F ............. F
96-bit timestamp #2 ....... I ............. I ........... F ............. F
96-bit timestamp #3 ....... I ............. I ........... F ............. F
===========================================================================
Total 1.5625 2.3866 0.7735 0.7243
Skipped 4 4 4 4
Failed 0 0 24 17
Ignored 24 24 0 7
With JIT:
MP_BENCH_TARGETS=pure_p,pure_u,pecl_p,pecl_u \
php -n -dextension=msgpack.so -dzend_extension=opcache.so \
-dpcre.jit=1 -dopcache.jit_buffer_size=64M -dopcache.jit=tracing -dopcache.enable=1 -dopcache.enable_cli=1 \
tests/bench.php
Example output
Filter: MessagePack\Tests\Perf\Filter\ListFilter
Rounds: 3
Iterations: 100000
===========================================================================
Test/Target Packer BufferUnpacker msgpack_pack msgpack_unpack
---------------------------------------------------------------------------
nil .................. 0.0001 ........ 0.0052 ...... 0.0053 ........ 0.0042
false ................ 0.0007 ........ 0.0060 ...... 0.0057 ........ 0.0043
true ................. 0.0008 ........ 0.0060 ...... 0.0056 ........ 0.0041
7-bit uint #1 ........ 0.0031 ........ 0.0046 ...... 0.0062 ........ 0.0041
7-bit uint #2 ........ 0.0021 ........ 0.0043 ...... 0.0062 ........ 0.0041
7-bit uint #3 ........ 0.0022 ........ 0.0044 ...... 0.0061 ........ 0.0040
5-bit sint #1 ........ 0.0030 ........ 0.0048 ...... 0.0062 ........ 0.0040
5-bit sint #2 ........ 0.0032 ........ 0.0046 ...... 0.0062 ........ 0.0040
5-bit sint #3 ........ 0.0031 ........ 0.0046 ...... 0.0062 ........ 0.0040
8-bit uint #1 ........ 0.0054 ........ 0.0079 ...... 0.0062 ........ 0.0050
8-bit uint #2 ........ 0.0051 ........ 0.0079 ...... 0.0064 ........ 0.0044
8-bit uint #3 ........ 0.0051 ........ 0.0082 ...... 0.0062 ........ 0.0044
16-bit uint #1 ....... 0.0077 ........ 0.0094 ...... 0.0065 ........ 0.0045
16-bit uint #2 ....... 0.0077 ........ 0.0094 ...... 0.0063 ........ 0.0045
16-bit uint #3 ....... 0.0077 ........ 0.0095 ...... 0.0064 ........ 0.0047
32-bit uint #1 ....... 0.0088 ........ 0.0119 ...... 0.0063 ........ 0.0043
32-bit uint #2 ....... 0.0089 ........ 0.0117 ...... 0.0062 ........ 0.0039
32-bit uint #3 ....... 0.0089 ........ 0.0118 ...... 0.0063 ........ 0.0044
64-bit uint #1 ....... 0.0097 ........ 0.0155 ...... 0.0063 ........ 0.0045
64-bit uint #2 ....... 0.0095 ........ 0.0153 ...... 0.0061 ........ 0.0045
64-bit uint #3 ....... 0.0096 ........ 0.0156 ...... 0.0063 ........ 0.0047
8-bit int #1 ......... 0.0053 ........ 0.0083 ...... 0.0062 ........ 0.0044
8-bit int #2 ......... 0.0052 ........ 0.0080 ...... 0.0062 ........ 0.0044
8-bit int #3 ......... 0.0052 ........ 0.0080 ...... 0.0062 ........ 0.0043
16-bit int #1 ........ 0.0089 ........ 0.0097 ...... 0.0069 ........ 0.0046
16-bit int #2 ........ 0.0075 ........ 0.0093 ...... 0.0063 ........ 0.0043
16-bit int #3 ........ 0.0075 ........ 0.0094 ...... 0.0062 ........ 0.0046
32-bit int #1 ........ 0.0086 ........ 0.0122 ...... 0.0063 ........ 0.0044
32-bit int #2 ........ 0.0087 ........ 0.0120 ...... 0.0066 ........ 0.0046
32-bit int #3 ........ 0.0086 ........ 0.0121 ...... 0.0060 ........ 0.0044
64-bit int #1 ........ 0.0096 ........ 0.0149 ...... 0.0060 ........ 0.0045
64-bit int #2 ........ 0.0096 ........ 0.0157 ...... 0.0062 ........ 0.0044
64-bit int #3 ........ 0.0096 ........ 0.0160 ...... 0.0063 ........ 0.0046
64-bit int #4 ........ 0.0097 ........ 0.0157 ...... 0.0061 ........ 0.0044
64-bit float #1 ...... 0.0079 ........ 0.0153 ...... 0.0056 ........ 0.0044
64-bit float #2 ...... 0.0079 ........ 0.0152 ...... 0.0057 ........ 0.0045
64-bit float #3 ...... 0.0079 ........ 0.0155 ...... 0.0057 ........ 0.0044
fix string #1 ........ 0.0010 ........ 0.0045 ...... 0.0071 ........ 0.0044
fix string #2 ........ 0.0048 ........ 0.0075 ...... 0.0070 ........ 0.0060
fix string #3 ........ 0.0048 ........ 0.0086 ...... 0.0068 ........ 0.0060
fix string #4 ........ 0.0050 ........ 0.0088 ...... 0.0070 ........ 0.0059
8-bit string #1 ...... 0.0081 ........ 0.0129 ...... 0.0069 ........ 0.0062
8-bit string #2 ...... 0.0086 ........ 0.0128 ...... 0.0069 ........ 0.0065
8-bit string #3 ...... 0.0086 ........ 0.0126 ...... 0.0115 ........ 0.0065
16-bit string #1 ..... 0.0105 ........ 0.0137 ...... 0.0128 ........ 0.0068
16-bit string #2 ..... 0.1510 ........ 0.1486 ...... 0.1526 ........ 0.1391
32-bit string ........ 0.1517 ........ 0.1475 ...... 0.1504 ........ 0.1370
wide char string #1 .. 0.0044 ........ 0.0085 ...... 0.0067 ........ 0.0057
wide char string #2 .. 0.0081 ........ 0.0125 ...... 0.0069 ........ 0.0063
8-bit binary #1 ........... I ............. I ........... F ............. I
8-bit binary #2 ........... I ............. I ........... F ............. I
8-bit binary #3 ........... I ............. I ........... F ............. I
16-bit binary ............. I ............. I ........... F ............. I
32-bit binary ............. I ............. I ........... F ............. I
fix array #1 ......... 0.0014 ........ 0.0059 ...... 0.0132 ........ 0.0055
fix array #2 ......... 0.0146 ........ 0.0156 ...... 0.0155 ........ 0.0148
fix array #3 ......... 0.0211 ........ 0.0229 ...... 0.0179 ........ 0.0180
16-bit array #1 ...... 0.0673 ........ 0.0498 ...... 0.0343 ........ 0.0388
16-bit array #2 ........... S ............. S ........... S ............. S
32-bit array .............. S ............. S ........... S ............. S
complex array ............. I ............. I ........... F ............. F
fix map #1 ................ I ............. I ........... F ............. I
fix map #2 ........... 0.0148 ........ 0.0180 ...... 0.0156 ........ 0.0179
fix map #3 ................ I ............. I ........... F ............. I
fix map #4 ........... 0.0252 ........ 0.0201 ...... 0.0214 ........ 0.0167
16-bit map #1 ........ 0.1027 ........ 0.0836 ...... 0.0388 ........ 0.0510
16-bit map #2 ............. S ............. S ........... S ............. S
32-bit map ................ S ............. S ........... S ............. S
complex map .......... 0.1104 ........ 0.1010 ...... 0.0556 ........ 0.0602
fixext 1 .................. I ............. I ........... F ............. F
fixext 2 .................. I ............. I ........... F ............. F
fixext 4 .................. I ............. I ........... F ............. F
fixext 8 .................. I ............. I ........... F ............. F
fixext 16 ................. I ............. I ........... F ............. F
8-bit ext ................. I ............. I ........... F ............. F
16-bit ext ................ I ............. I ........... F ............. F
32-bit ext ................ I ............. I ........... F ............. F
32-bit timestamp #1 ....... I ............. I ........... F ............. F
32-bit timestamp #2 ....... I ............. I ........... F ............. F
64-bit timestamp #1 ....... I ............. I ........... F ............. F
64-bit timestamp #2 ....... I ............. I ........... F ............. F
64-bit timestamp #3 ....... I ............. I ........... F ............. F
96-bit timestamp #1 ....... I ............. I ........... F ............. F
96-bit timestamp #2 ....... I ............. I ........... F ............. F
96-bit timestamp #3 ....... I ............. I ........... F ............. F
===========================================================================
Total 0.9642 1.0909 0.8224 0.7213
Skipped 4 4 4 4
Failed 0 0 24 17
Ignored 24 24 0 7
Note that the msgpack extension (v2.1.2) doesn't support ext, bin and UTF-8 str types.
The library is released under the MIT License. See the bundled LICENSE file for details.
Author: rybakit
Source Code: https://github.com/rybakit/msgpack.php
License: MIT License
1619518440
Welcome to my Blog , In this article, you are going to learn the top 10 python tips and tricks.
âŠ
#python #python hacks tricks #python learning tips #python programming tricks #python tips #python tips and tricks #python tips and tricks advanced #python tips and tricks for beginners #python tips tricks and techniques #python tutorial #tips and tricks in python #tips to learn python #top 30 python tips and tricks for beginners
1647540000
The Substrate Knowledge Map provides information that youâas a Substrate hackathon participantâneed to know to develop a non-trivial application for your hackathon submission.
The map covers 6 main sections:
Each section contains basic information on each topic, with links to additional documentation for you to dig deeper. Within each section, you'll find a mix of quizzes and labs to test your knowledge as your progress through the map. The goal of the labs and quizzes is to help you consolidate what you've learned and put it to practice with some hands-on activities.
One question we often get is why learn the Substrate framework when we can write smart contracts to build decentralized applications?
The short answer is that using the Substrate framework and writing smart contracts are two different approaches.
Traditional smart contract platforms allow users to publish additional logic on top of some core blockchain logic. Since smart contract logic can be published by anyone, including malicious actors and inexperienced developers, there are a number of intentional safeguards and restrictions built around these public smart contract platforms. For example:
Fees: Smart contract developers must ensure that contract users are charged for the computation and storage they impose on the computers running their contract. With fees, block creators are protected from abuse of the network.
Sandboxed: A contract is not able to modify core blockchain storage or storage items of other contracts directly. Its power is limited to only modifying its own state, and the ability to make outside calls to other contracts or runtime functions.
Reversion: Contracts can be prone to undesirable situations that lead to logical errors when wanting to revert or upgrade them. Developers need to learn additional patterns such as splitting their contract's logic and data to ensure seamless upgrades.
These safeguards and restrictions make running smart contracts slower and more costly. However, it's important to consider the different developer audiences for contract development versus Substrate runtime development.
Building decentralized applications with smart contracts allows your community to extend and develop on top of your runtime logic without worrying about proposals, runtime upgrades, and so on. You can also use smart contracts as a testing ground for future runtime changes, but done in an isolated way that protects your network from any errors the changes might introduce.
In summary, smart contract development:
Unlike traditional smart contract development, Substrate runtime development offers none of the network protections or safeguards. Instead, as a runtime developer, you have total control over how the blockchain behaves. However, this level of control also means that there is a higher barrier to entry.
Substrate is a framework for building blockchains, which almost makes comparing it to smart contract development like comparing apples and oranges. With the Substrate framework, developers can build smart contracts but that is only a fraction of using Substrate to its full potential.
With Substrate, you have full control over the underlying logic that your network's nodes will run. You also have full access for modifying and controlling each and every storage item across your runtime modules. As you progress through this map, you'll discover concepts and techniques that will help you to unlock the potential of the Substrate framework, giving you the freedom to build the blockchain that best suits the needs of your application.
You'll also discover how you can upgrade the Substrate runtime with a single transaction instead of having to organize a community hard-fork. Upgradeability is one of the primary design features of the Substrate framework.
In summary, runtime development:
To learn more about using smart contracts within Substrate, refer to the Smart Contract - Overview page as well as the Polkadot Builders Guide.
If you need any community support, please join the following channels based on the area where you need help:
Alternatively, also look for support on Stackoverflow where questions are tagged with "substrate" or on the Parity Subport repo.
Use the following links to explore the sites and resources available on each:
Substrate Developer Hub has the most comprehensive all-round coverage about Substrate, from a "big picture" explanation of architecture to specific technical concepts. The site also provides tutorials to guide you as your learn the Substrate framework and the API reference documentation. You should check this site first if you want to look up information about Substrate runtime development. The site consists of:
Knowledge Base: Explaining the foundational concepts of building blockchain runtimes using Substrate.
Tutorials: Hand-on tutorials for developers to follow. The first SIX tutorials show the fundamentals in Substrate and are recommended for every Substrate learner to go through.
How-to Guides: These resources are like the O'Reilly cookbook series written in a task-oriented way for readers to get the job done. Some examples of the topics overed include:
API docs: Substrate API reference documentation.
Substrate Node Template provides a light weight, minimal Substrate blockchain node that you can set up as a local development environment.
Substrate Front-end template provides a front-end interface built with React using Polkadot-JS API to connect to any Substrate node. Developers are encouraged to start new Substrate projects based on these templates.
If you face any technical difficulties and need support, feel free to join the Substrate Technical matrix channel and ask your questions there.
Polkadot Wiki documents the specific behavior and mechanisms of the Polkadot network. The Polkadot network allows multiple blockchains to connect and pass messages to each other. On the wiki, you can learn about how Polkadotâbuilt using Substrateâis customized to support inter-blockchain message passing.
Polkadot JS API doc: documents how to use the Polkadot-JS API. This JavaScript-based API allows developers to build custom front-ends for their blockchains and applications. Polkadot JS API provides a way to connect to Substrate-based blockchains to query runtime metadata and send transactions.
ð Submit your answers to Quiz #1
Here you will set up your local machine to install the Rust compilerâensuring that you have both stable and nightly versions installed. Both stable and nightly versions are required because currently a Substrate runtime is compiled to a native binary using the stable Rust compiler, then compiled to a WebAssembly (WASM) binary, which only the nightly Rust compiler can do.
Also refer to:
ð Complete Lab #1: Run a Substrate node
Polkadot JS Apps is the canonical front-end to interact with any Substrate-based chain.
You can configure whichever endpoint you want it to connected to, even to your localhost
running node. Refer to the following two diagrams.
ð Complete Quiz #2
ð Complete Lab #2: Using Polkadot-JS Apps
Notes: If you are connecting Apps to a custom chain (or your locally-running node), you may need to specify your chain's custom data types in JSON under Settings > Developer.
Polkadot-JS Apps only receives a series of bytes from the blockchain. It is up to the developer to tell it how to decode and interpret these custom data type. To learn more on this, refer to:
You will also need to create an account. To do so, follow these steps on account generation. You'll learn that you can also use the Polkadot-JS Browser Plugin (a Metamask-like browser extension to manage your Substrate accounts) and it will automatically be imported into Polkadot-JS Apps.
Notes: When you run a Substrate chain in development mode (with the
--dev
flag), well-known accounts (Alice
,Bob
,Charlie
, etc.) are always created for you.
ð Complete Lab #3: Create an Account
You need to know some Rust programming concepts and have a good understanding on how blockchain technology works in order to make the most of developing with Substrate. The following resources will help you brush up in these areas.
You will need familiarize yourself with Rust to understand how Substrate is built and how to make the most of its capabilities.
If you are new to Rust, or need a brush up on your Rust knowledge, please refer to The Rust Book. You could still continue learning about Substrate without knowing Rust, but we recommend you come back to this section whenever in doubt about what any of the Rust syntax you're looking at means. Here are the parts of the Rust book we recommend you familiarize yourself with:
Given that you'll be writing a blockchain runtime, you need to know what a blockchain is, and how it works. The **Web3 Blockchain Fundamental MOOC Youtube video series provides a good basis for understanding key blockchain concepts and how blockchains work.
The lectures we recommend you watch are: lectures 1 - 7 and lecture 10. That's 8 lectures, or about 4 hours of video.
ð Complete Quiz #3
To know more about the high level architecture of Substrate, please go through the Knowledge Base articles on Getting Started: Overview and Getting Started: Architecture.
In this document, we assume you will develop a Substrate runtime with FRAME (v2). This is what a Substrate node consists of.
Each node has many components that manage things like the transaction queue, communicating over a P2P network, reaching consensus on the state of the blockchain, and the chain's actual runtime logic (aka the blockchain runtime). Each aspect of the node is interesting in its own right, and the runtime is particularly interesting because it contains the business logic (aka "state transition function") that codifies the chain's functionality. The runtime contains a collection of pallets that are configured to work together.
On the node level, Substrate leverages libp2p for the p2p networking layer and puts the transaction pool, consensus mechanism, and underlying data storage (a key-value database) on the node level. These components all work "under the hood", and in this knowledge map we won't cover them in detail except for mentioning their existence.
ð Complete Quiz #4
In our Developer Hub, we have a thorough coverage on various subjects you need to know to develop with Substrate. So here we just list out the key topics and reference back to Developer Hub. Please go through the following key concepts and the directed resources to know the fundamentals of runtime development.
Key Concept: Runtime, this is where the blockchain state transition function (the blockchain application-specific logic) is defined. It is about composing multiple pallets (can be understood as Rust modules) together in the runtime and hooking them up together.
Runtime Development: Execution, this article describes how a block is produced, and how transactions are selected and executed to reach the next "stage" in the blockchain.
Runtime Develpment: Pallets, this article describes what the basic structure of a Substrate pallet is consists of.
Runtime Development: FRAME, this article gives a high level overview of the system pallets Substrate already implements to help you quickly develop as a runtime engineer. Have a quick skim so you have a basic idea of the different pallets Substrate is made of.
ð Complete Lab #4: Adding a Pallet into a Runtime
Runtime Development: Storage, this article describes how data is stored on-chain and how you could access them.
Runtime Development: Events & Errors, this page describe how external parties know what has happened in the blockchain, via the emitted events and errors when executing transactions.
Notes: All of the above concepts we leverage on the
#[pallet::*]
macro to define them in the code. If you are interested to learn more about what other types of pallet macros exist go to the FRAME macro API documentation and this doc on some frequently used Substrate macros.
ð Complete Lab #5: Building a Proof-of-Existence dApp
ð Complete Lab #6: Building a Substrate Kitties dApp
ð Complete Quiz #5
Polkadot JS API is the javascript API for Substrate. By using it you can build a javascript front end or utility and interact with any Substrate-based blockchain.
The Substrate Front-end Template is an example of using Polkadot JS API in a React front-end.
ð Complete Lab #7: Using Polkadot-JS API
ð Complete Quiz #6: Using Polkadot-JS API
Learn about the difference between smart contract development vs Substrate runtime development, and when to use each here.
In Substrate, you can program smart contracts using ink!.
ð Complete Quiz #7: Using ink!
A lot ð
On-chain runtime upgrades. We have a tutorial on On-chain (forkless) Runtime Upgrade. This tutorial introduces how to perform and schedule a runtime upgrade as an on-chain transaction.
About transaction weight and fee, and benchmarking your runtime to determine the proper transaction cost.
There are certain limits to on-chain logic. For instance, computation cannot be too intensive that it affects the block output time, and computation must be deterministic. This means that computation that relies on external data fetching cannot be done on-chain. In Substrate, developers can run these types of computation off-chain and have the result sent back on-chain via extrinsics.
Tightly- and Loosely-coupled pallets, calling one pallet's functions from another pallet via trait specification.
Blockchain Consensus Mechansim, and a guide on customizing it to proof-of-work here.
Parachains: one key feature of Substrate is the capability of becoming a parachain for relay chains like Polkadot. You can develop your own application-specific logic in your chain and rely on the validator community of the relay chain to secure your network, instead of building another validator community yourself. Learn more with the following resources:
Author: substrate-developer-hub
Source Code: https://github.com/substrate-developer-hub/hackathon-knowledge-map
License:
1619510796
Welcome to my Blog, In this article, we will learn python lambda function, Map function, and filter function.
Lambda function in python: Lambda is a one line anonymous function and lambda takes any number of arguments but can only have one expression and python lambda syntax is
Syntax: x = lambda arguments : expression
Now i will show you some python lambda function examples:
#python #anonymous function python #filter function in python #lambda #lambda python 3 #map python #python filter #python filter lambda #python lambda #python lambda examples #python map
1635917640
ãã®ã¢ãžã¥ãŒã«ã§ã¯ãRustã§ããã·ã¥ãããè€åããŒã¿åãæäœããæ¹æ³ã«ã€ããŠèª¬æããŸããããã·ã¥ãããã®ãããªã³ã¬ã¯ã·ã§ã³å ã®ããŒã¿ãå埩åŠçããã«ãŒãåŒãå®è£ ããæ¹æ³ãåŠã³ãŸããæŒç¿ãšããŠãèŠæ±ãããæ³šæãã«ãŒãããæ¡ä»¶ããã¹ãããããŸããŸãªã¿ã€ãã®ããŒã¿ãåŠçããããšã«ãã£ãŠè»ãäœæããRustããã°ã©ã ãäœæããŸãã
ééã³å Žã¯éã³ã³ãã€ã©ã«ãã©ãŠã¶ã€ã³ã¿ãã§ãŒã¹ã§ããèšèªãããŒã«ã«ã«ã€ã³ã¹ããŒã«ããåããŸãã¯ã³ã³ãã€ã©ãå©çšã§ããªãå Žåã¯ãPlaygroundã䜿çšããŠRustã³ãŒãã®èšè¿°ã詊ãããšãã§ããŸãããã®ã³ãŒã¹å šäœãéããŠããµã³ãã«ã³ãŒããšæŒç¿ãžã®Playgroundãªã³ã¯ãæäŸããŸããçŸæç¹ã§RustããŒã«ãã§ãŒã³ã䜿çšã§ããªãå Žåã§ããã³ãŒããæäœã§ããŸãã
Rust Playgroundã§å®è¡ããããã¹ãŠã®ã³ãŒãã¯ãããŒã«ã«ã®éçºç°å¢ã§ã³ã³ãã€ã«ããŠå®è¡ããããšãã§ããŸããã³ã³ãã¥ãŒã¿ãŒããRustã³ã³ãã€ã©ãŒãšå¯Ÿè©±ããããšãèºèºããªãã§ãã ãããRust Playgroundã®è©³çްã«ã€ããŠã¯ãWhat isRustïŒãã芧ãã ãããã¢ãžã¥ãŒã«ã
ãã®ã¢ãžã¥ãŒã«ã§ã¯ã次ã®ããšãè¡ããŸãã
Rustã®ãã1ã€ã®äžè¬çãªã³ã¬ã¯ã·ã§ã³ã®çš®é¡ã¯ãããã·ã¥ãããã§ãããã®HashMap<K, V>
åã¯ãåããŒK
ããã®å€ã«ãããã³ã°ããããšã«ãã£ãŠããŒã¿ãæ ŒçŽããŸãV
ããã¯ãã«å
ã®ããŒã¿ã¯æŽæ°ã€ã³ããã¯ã¹ã䜿çšããŠã¢ã¯ã»ã¹ãããŸãããããã·ã¥ãããå
ã®ããŒã¿ã¯ããŒã䜿çšããŠã¢ã¯ã»ã¹ãããŸãã
ããã·ã¥ãããã¿ã€ãã¯ããªããžã§ã¯ããããã·ã¥ããŒãã«ãèŸæžãªã©ã®ããŒã¿é ç®ã®å€ãã®ããã°ã©ãã³ã°èšèªã§äœ¿çšãããŸãã
ãã¯ãã«ã®ããã«ãããã·ã¥ãããã¯æ¡åŒµå¯èœã§ããããŒã¿ã¯ããŒãã«æ ŒçŽãããããã·ã¥ãããã¢ã€ãã ãžã®ã¢ã¯ã»ã¹ã¯å®è¡æã«ãã§ãã¯ãããŸãã
次ã®äŸã§ã¯ãæžè©ã远跡ããããã®ããã·ã¥ããããå®çŸ©ããŠããŸããããã·ã¥ãããããŒã¯æ¬ã®ååã§ãããå€ã¯èªè ã®ã¬ãã¥ãŒã§ãã
use std::collections::HashMap;
let mut reviews: HashMap<String, String> = HashMap::new();
reviews.insert(String::from("Ancient Roman History"), String::from("Very accurate."));
reviews.insert(String::from("Cooking with Rhubarb"), String::from("Sweet recipes."));
reviews.insert(String::from("Programming in Rust"), String::from("Great examples."));
ãã®ã³ãŒããããã«è©³ãã調ã¹ãŠã¿ãŸããããæåã®è¡ã«ãæ°ããã¿ã€ãã®æ§æã衚瀺ãããŸãã
use std::collections::HashMap;
ãã®use
ã³ãã³ãã¯ãRustæšæºã©ã€ãã©ãªã®äžéšHashMap
ããã®å®çŸ©ãcollections
ããã°ã©ã ã®ã¹ã³ãŒãã«åã蟌ã¿ãŸãããã®æ§æã¯ãä»ã®ããã°ã©ãã³ã°èšèªãã€ã³ããŒããšåŒã¶ãã®ãšäŒŒãŠããŸãã
HashMap::new
ã¡ãœããã䜿çšããŠç©ºã®ããã·ã¥ããããäœæããŸããreviews
å¿
èŠã«å¿ããŠããŒãšå€ã远å ãŸãã¯åé€ã§ããããã«ã倿°ãå¯å€ãšããŠå®£èšããŸãããã®äŸã§ã¯ãããã·ã¥ãããã®ããŒãšå€ã®äž¡æ¹ãString
ã¿ã€ãã䜿çšããŠããŸãã
let mut reviews: HashMap<String, String> = HashMap::new();
ãã®insert(<key>, <value>)
ã¡ãœããã䜿çšããŠãããã·ã¥ãããã«èŠçŽ ã远å ããŸããã³ãŒãã§ã¯ãæ§æã¯<hash_map_name>.insert()
次ã®ãšããã§ãã
reviews.insert(String::from("Ancient Roman History"), String::from("Very accurate."));
ããã·ã¥ãããã«ããŒã¿ã远å ããåŸãget(<key>)
ã¡ãœããã䜿çšããŠããŒã®ç¹å®ã®å€ãååŸã§ããŸãã
// Look for a specific review
let book: &str = "Programming in Rust";
println!("\nReview for \'{}\': {:?}", book, reviews.get(book));
åºåã¯æ¬¡ã®ãšããã§ãã
Review for 'Programming in Rust': Some("Great examples.")
ããŒã
åºåã«ã¯ãæžè©ãåãªãããã°ãããäŸãã§ã¯ãªããSomeïŒ "ãã°ãããäŸã"ïŒããšããŠè¡šç€ºãããŠããããšã«æ³šæããŠãã ãããget
ã¡ãœããã¯Option<&Value>
åãè¿ããããRustã¯ã¡ãœããåŒã³åºãã®çµæããSomeïŒïŒã衚èšã§ã©ããããŸãã
ãã®.remove()
ã¡ãœããã䜿çšããŠãããã·ã¥ããããããšã³ããªãåé€ã§ããŸããget
ç¡å¹ãªããã·ã¥ãããããŒã«å¯ŸããŠã¡ãœããã䜿çšãããšãget
ã¡ãœããã¯ããªãããè¿ããŸãã
// Remove book review
let obsolete: &str = "Ancient Roman History";
println!("\n'{}\' removed.", obsolete);
reviews.remove(obsolete);
// Confirm book review removed
println!("\nReview for \'{}\': {:?}", obsolete, reviews.get(obsolete));
åºåã¯æ¬¡ã®ãšããã§ãã
'Ancient Roman History' removed.
Review for 'Ancient Roman History': None
ãã®ã³ãŒãã詊ããŠããã®RustPlaygroundã§ããã·ã¥ããããæäœã§ããŸãã
æŒç¿ïŒããã·ã¥ãããã䜿çšããŠæ³šæã远跡ãã
ãã®æŒç¿ã§ã¯ãããã·ã¥ãããã䜿çšããããã«èªåè»å·¥å Žã®ããã°ã©ã ã倿ŽããŸãã
ããã·ã¥ãããããŒãšå€ã®ãã¢ã䜿çšããŠãè»ã®æ³šæã«é¢ãã詳现ã远跡ããåºåã衚瀺ããŸããç¹°ãè¿ãã«ãªããŸãããããªãã®èª²é¡ã¯ããµã³ãã«ã³ãŒãã宿ãããŠã³ã³ãã€ã«ããŠå®è¡ããããšã§ãã
ãã®æŒç¿ã®ãµã³ãã«ã³ãŒãã§äœæ¥ããã«ã¯ã次ã®2ã€ã®ãªãã·ã§ã³ããããŸãã
ããŒã
ãµã³ãã«ã³ãŒãã§ã
todo!
ãã¯ããæ¢ããŸãããã®ãã¯ãã¯ãå®äºãããæŽæ°ããå¿ èŠãããã³ãŒãã瀺ããŸãã
æåã®ã¹ãããã¯ãæ¢åã®ããã°ã©ã ã³ãŒããååŸããããšã§ãã
car_quality
ãcar_factory
ããã³main
æ©èœããæ¬¡ã®ã³ãŒããã³ããŒããŠããŒã«ã«éçºç°å¢ã§ç·šéãã
ãããã®æºåãããRustPlaygroundã§ã³ãŒããéããŸãã
#[derive(PartialEq, Debug)]
struct Car { color: String, motor: Transmission, roof: bool, age: (Age, u32) }
#[derive(PartialEq, Debug)]
enum Transmission { Manual, SemiAuto, Automatic }
#[derive(PartialEq, Debug)]
enum Age { New, Used }
// Get the car quality by testing the value of the input argument
// - miles (u32)
// Return tuple with car age ("New" or "Used") and mileage
fn car_quality (miles: u32) -> (Age, u32) {
// Check if car has accumulated miles
// Return tuple early for Used car
if miles > 0 {
return (Age::Used, miles);
}
// Return tuple for New car, no need for "return" keyword or semicolon
(Age::New, miles)
}
// Build "Car" using input arguments
fn car_factory(order: i32, miles: u32) -> Car {
let colors = ["Blue", "Green", "Red", "Silver"];
// Prevent panic: Check color index for colors array, reset as needed
// Valid color = 1, 2, 3, or 4
// If color > 4, reduce color to valid index
let mut color = order as usize;
if color > 4 {
// color = 5 --> index 1, 6 --> 2, 7 --> 3, 8 --> 4
color = color - 4;
}
// Add variety to orders for motor type and roof type
let mut motor = Transmission::Manual;
let mut roof = true;
if order % 3 == 0 { // 3, 6, 9
motor = Transmission::Automatic;
} else if order % 2 == 0 { // 2, 4, 8, 10
motor = Transmission::SemiAuto;
roof = false;
} // 1, 5, 7, 11
// Return requested "Car"
Car {
color: String::from(colors[(color-1) as usize]),
motor: motor,
roof: roof,
age: car_quality(miles)
}
}
fn main() {
// Initialize counter variable
let mut order = 1;
// Declare a car as mutable "Car" struct
let mut car: Car;
// Order 6 cars, increment "order" for each request
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #2: Used, Convertible
order = order + 1;
car = car_factory(order, 2000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #3: New, Hard top
order = order + 1;
car = car_factory(order, 0);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #4: New, Convertible
order = order + 1;
car = car_factory(order, 0);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #5: Used, Hard top
order = order + 1;
car = car_factory(order, 3000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
}
2. ããã°ã©ã ããã«ãããŸããæ¬¡ã®ã»ã¯ã·ã§ã³ã«é²ãåã«ãã³ãŒããã³ã³ãã€ã«ãããŠå®è¡ãããããšã確èªããŠãã ããã
次ã®åºåã衚瀺ãããŸãã
1: Used, Hard top = true, Manual, Blue, 1000 miles
2: Used, Hard top = false, SemiAuto, Green, 2000 miles
3: New, Hard top = true, Automatic, Red, 0 miles
4: New, Hard top = false, SemiAuto, Silver, 0 miles
5: Used, Hard top = true, Manual, Blue, 3000 miles
6: Used, Hard top = true, Automatic, Green, 4000 miles
çŸåšã®ããã°ã©ã ã¯ãåè»ã®æ³šæãåŠçããåæ³šæãå®äºããåŸã«èŠçŽãå°å·ããŸããcar_factory
颿°ãåŒã³åºããã³ã«Car
ãæ³šæã®è©³çްãå«ãæ§é äœãè¿ãããæ³šæãå®è¡ãããŸããçµæã¯car
倿°ã«æ ŒçŽãããŸãã
ãæ°ã¥ããããããŸãããããã®ããã°ã©ã ã«ã¯ããã€ãã®éèŠãªæ©èœããããŸããããã¹ãŠã®æ³šæã远跡ããŠããããã§ã¯ãããŸãããcar
倿°ã¯ãçŸåšã®æ³šæã®è©³çްã®ã¿ãä¿æããŠããŸãã颿°car
ã®çµæã§å€æ°ãæŽæ°ããããã³car_factory
ã«ãåã®é åºã®è©³çްãäžæžããããŸãã
ãã¡ã€ãªã³ã°ã·ã¹ãã ã®ããã«ãã¹ãŠã®æ³šæã远跡ããããã«ãããã°ã©ã ãæŽæ°ããå¿
èŠããããŸãããã®ç®çã®ããã«ã<KãV>ãã¢ã§ããã·ã¥ããããå®çŸ©ããŸããããã·ã¥ãããããŒã¯ãè»ã®æ³šæçªå·ã«å¯Ÿå¿ããŸããããã·ã¥ãããå€ã¯ãCar
æ§é äœã§å®çŸ©ãããŠããããããã®æ³šæã®è©³çްã«ãªããŸãã
main
颿°ã®å
é ãæåã®äžæ¬åŒ§ã®çŽåŸã«æ¬¡ã®ã³ãŒãã远å ããŸã{
ã// Initialize a hash map for the car orders
// - Key: Car order number, i32
// - Value: Car order details, Car struct
use std::collections::HashMap;
let mut orders: HashMap<i32, Car> = HashMap;
2. orders
ããã·ã¥ããããäœæããã¹ããŒãã¡ã³ãã®æ§æã®åé¡ãä¿®æ£ããŸãã
ãã³ã
ããã·ã¥ããããæåããäœæããŠããã®ã§ããããããã®
new()
ã¡ãœããã䜿çšããããšããå§ãããŸãã
3. ããã°ã©ã ããã«ãããŸããæ¬¡ã®ã»ã¯ã·ã§ã³ã«é²ãåã«ãã³ãŒããã³ã³ãã€ã«ãããŠããããšã確èªããŠãã ãããã³ã³ãã€ã©ããã®èŠåã¡ãã»ãŒãžã¯ç¡èŠããŠããŸããŸããã
次ã®ã¹ãããã¯ãå±¥è¡ãããåèªåè»æ³šæãããã·ã¥ãããã«è¿œå ããããšã§ãã
ãã®main
颿°ã§ã¯ãcar_factory
è»ã®æ³šæããšã«é¢æ°ãåŒã³åºããŸããæ³šæãå±¥è¡ãããåŸãprintln!
ãã¯ããåŒã³åºããŠãcar
倿°ã«æ ŒçŽãããŠããæ³šæã®è©³çްã衚瀺ããŸãã
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
æ°ããããã·ã¥ãããã§æ©èœããããã«ããããã®ã³ãŒãã¹ããŒãã¡ã³ããä¿®æ£ããŸãã
car_factory
颿°ã®åŒã³åºãã¯ä¿æããŸããè¿ãããåCar
æ§é äœã¯ãããã·ã¥ãããã®<KãV>ãã¢ã®äžéšãšããŠæ ŒçŽãããŸããprintln!
ãã¯ãã®åŒã³åºããæŽæ°ããŠãããã·ã¥ãããã«ä¿åãããŠããæ³šæã®è©³çްã衚瀺ããŸããmain
颿°ã§ã颿°ã®åŒã³åºãcar_factory
ãšããã«äŒŽãprintln!
ãã¯ãã®åŒã³åºããèŠã€ããŸãã// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
2. ãã¹ãŠã®èªåè»æ³šæã®ã¹ããŒãã¡ã³ãã®å®å šãªã»ãããæ¬¡ã®æ¹èšãããã³ãŒãã«çœ®ãæããŸãã
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #2: Used, Convertible
order = order + 1;
car = car_factory(order, 2000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #3: New, Hard top
order = order + 1;
car = car_factory(order, 0);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #4: New, Convertible
order = order + 1;
car = car_factory(order, 0);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #5: Used, Hard top
order = order + 1;
car = car_factory(order, 3000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
3. ä»ããããã°ã©ã ããã«ãããããšãããšãã³ã³ãã€ã«ãšã©ãŒã衚瀺ãããŸãã<KãV>ãã¢ãorders
ããã·ã¥ãããã«è¿œå ããã¹ããŒãã¡ã³ãã«æ§æäžã®åé¡ããããŸããåé¡ããããŸããïŒå
ã«é²ãã§ãããã·ã¥ãããã«é åºã远å ããåã¹ããŒãã¡ã³ãã®åé¡ãä¿®æ£ããŠãã ããã
ãã³ã
orders
ããã·ã¥ãããã«çŽæ¥å€ãå²ãåœãŠãããšã¯ã§ããŸãããæ¿å ¥ãè¡ãã«ã¯ã¡ãœããã䜿çšããå¿ èŠããããŸãã
ããã°ã©ã ãæ£åžžã«ãã«ãããããšã次ã®åºåã衚瀺ãããŸãã
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("Used", 1000) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 2000) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("New", 0) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("New", 0) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("Used", 3000) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 4000) })
æ¹èšãããã³ãŒãã®åºåãç°ãªãããšã«æ³šæããŠãã ãããprintln!
ãã¯ããã£ã¹ãã¬ã€ã®å
容Car
åå€ã瀺ãããšã«ãã£ãŠãæ§é äœãšå¯Ÿå¿ãããã£ãŒã«ãåã
æ¬¡ã®æŒç¿ã§ã¯ãã«ãŒãåŒã䜿çšããŠã³ãŒãã®åé·æ§ãæžãããŸãã
forãwhileãããã³loopåŒã䜿çšããŸã
å€ãã®å Žåãããã°ã©ã ã«ã¯ããã®å Žã§ç¹°ãè¿ãå¿
èŠã®ããã³ãŒãã®ãããã¯ããããŸããã«ãŒãåŒã䜿çšããŠãç¹°ãè¿ãã®å®è¡æ¹æ³ãããã°ã©ã ã«æç€ºã§ããŸããé»è©±åž³ã®ãã¹ãŠã®ãšã³ããªãå°å·ããã«ã¯ãã«ãŒãåŒã䜿çšããŠãæåã®ãšã³ããªããæåŸã®ãšã³ããªãŸã§å°å·ããæ¹æ³ãããã°ã©ã ã«æç€ºã§ããŸãã
Rustã¯ãããã°ã©ã ã«ã³ãŒãã®ãããã¯ãç¹°ãè¿ãããããã®3ã€ã®ã«ãŒãåŒãæäŸããŸãã
loop
ïŒæå忢ãçºçããªãéããç¹°ãè¿ããŸããwhile
ïŒæ¡ä»¶ãçã®ãŸãŸã§ç¹°ãè¿ããŸããfor
ïŒã³ã¬ã¯ã·ã§ã³å
ã®ãã¹ãŠã®å€ã«å¯ŸããŠç¹°ãè¿ããŸãããã®åå ã§ã¯ããããã®åã«ãŒãåŒãèŠãŠãããŸãã
loop
åŒã¯ãç¡éã«ãŒããäœæããŸãããã®ããŒã¯ãŒãã䜿çšãããšãåŒã®æ¬æã§ã¢ã¯ã·ã§ã³ãç¶ç¶çã«ç¹°ãè¿ãããšãã§ããŸããã«ãŒãã忢ãããããã®çŽæ¥ã¢ã¯ã·ã§ã³ãå®è¡ãããŸã§ãã¢ã¯ã·ã§ã³ãç¹°ãè¿ãããŸãã
次ã®äŸã§ã¯ããWe loopforeverïŒããšããããã¹ããåºåããŸãããããŠããã¯ããèªäœã§æ¢ãŸããŸãããprintln!
ã¢ã¯ã·ã§ã³ã¯ç¹°ãè¿ãç¶ããŸãã
loop {
println!("We loop forever!");
}
loop
åŒã䜿çšããå Žåãã«ãŒãã忢ããå¯äžã®æ¹æ³ã¯ãããã°ã©ããŒãšããŠçŽæ¥ä»å
¥ããå Žåã§ããç¹å®ã®ã³ãŒãã远å ããŠã«ãŒãã忢ããããCtrl + Cãªã©ã®ããŒããŒãåœä»€ãå
¥åããŠããã°ã©ã ã®å®è¡ã忢ãããã§ããŸãã
loop
åŒã忢ããæãäžè¬çãªæ¹æ³ã¯ãbreak
ããŒã¯ãŒãã䜿çšããŠãã¬ãŒã¯ãã€ã³ããèšå®ããããšã§ãã
loop {
// Keep printing, printing, printing...
println!("We loop forever!");
// On the other hand, maybe we should stop!
break;
}
ããã°ã©ã ãbreak
ããŒã¯ãŒããæ€åºãããšãloop
åŒã®æ¬äœã§ã¢ã¯ã·ã§ã³ã®å®è¡ã忢ããæ¬¡ã®ã³ãŒãã¹ããŒãã¡ã³ãã«é²ã¿ãŸãã
break
ããŒã¯ãŒãã¯ãç¹å¥ãªæ©èœãæããã«ããloop
衚çŸããbreak
ããŒã¯ãŒãã䜿çšãããšãåŒæ¬äœã§ã®ã¢ã¯ã·ã§ã³ã®ç¹°ãè¿ãã忢ããããšãããã¬ãŒã¯ãã€ã³ãã§å€ãè¿ãããšãã§ããŸãã
次ã®äŸã¯break
ãloop
åŒã§ããŒã¯ãŒãã䜿çšããŠå€ãè¿ãæ¹æ³ã瀺ããŠããŸãã
let mut counter = 1;
// stop_loop is set when loop stops
let stop_loop = loop {
counter *= 2;
if counter > 100 {
// Stop loop, return counter value
break counter;
}
};
// Loop should break when counter = 128
println!("Break the loop at counter = {}.", stop_loop);
åºåã¯æ¬¡ã®ãšããã§ãã
Break the loop at counter = 128.
ç§ãã¡ã®loop
衚çŸã®æ¬äœã¯ããããã®é£ç¶ããã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
stop_loop
倿°ã宣èšããŸããloop
åŒã®çµæã«ãã€ã³ãããããã«ããã°ã©ã ã«æç€ºããŸããloop
åŒã®æ¬äœã§ã¢ã¯ã·ã§ã³ãå®è¡ããŸãïŒcounter
å€ãçŸåšã®å€ã®2åã«ã€ã³ã¯ãªã¡ã³ãããŸããcounter
å€ã確èªããŠãã ãããcounter
å€ã100以äžã§ããã«ãŒãããæãåºãã
counter
å€ãè¿ããŸãã
4. ããcounter
å€ã100以äžã§ã¯ãããŸããã
ã«ãŒãæ¬äœã§ã¢ã¯ã·ã§ã³ãç¹°ãè¿ããŸãã
5. stop_loop
å€ãåŒã®counter
çµæã§ããå€ã«èšå®ããŸãloop
ã
loop
åŒæ¬äœã¯ãè€æ°ã®ãã¬ãŒã¯ãã€ã³ããæã€ããšãã§ããŸããåŒã«è€æ°ã®ãã¬ãŒã¯ãã€ã³ããããå Žåããã¹ãŠã®ãã¬ãŒã¯ãã€ã³ãã¯åãã¿ã€ãã®å€ãè¿ãå¿
èŠããããŸãããã¹ãŠã®å€ã¯ãæŽæ°åãæåååãããŒã«åãªã©ã§ããå¿
èŠããããŸãããã¬ãŒã¯ãã€ã³ããæç€ºçã«å€ãè¿ããªãå Žåãããã°ã©ã ã¯åŒã®çµæã空ã®ã¿ãã«ãšããŠè§£éããŸã()
ã
while
ã«ãŒãã¯ãæ¡ä»¶åŒã䜿çšããŠããŸããæ¡ä»¶åŒãçã§ããéããã«ãŒããç¹°ãè¿ãããŸãããã®ããŒã¯ãŒãã䜿çšãããšãæ¡ä»¶åŒãfalseã«ãªããŸã§ãåŒæ¬äœã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã
while
ã«ãŒãã¯ãããŒã«æ¡ä»¶åŒãè©äŸ¡ããããšããå§ãŸããŸããæ¡ä»¶åŒããšè©äŸ¡ãããtrue
ãšãæ¬äœã®ã¢ã¯ã·ã§ã³ãå®è¡ãããŸããã¢ã¯ã·ã§ã³ãå®äºãããšãå¶åŸ¡ã¯æ¡ä»¶åŒã«æ»ããŸããæ¡ä»¶åŒããšè©äŸ¡ãããfalse
ãšãwhile
åŒã¯åæ¢ããŸãã
次ã®äŸã§ã¯ãããã°ããã«ãŒãããŸã...ããšããããã¹ããåºåããŸããã«ãŒããç¹°ãè¿ããã³ã«ããã«ãŠã³ãã5æªæºã§ããããšããæ¡ä»¶ããã¹ããããŸããæ¡ä»¶ãçã®ãŸãŸã§ããéãåŒæ¬äœã®ã¢ã¯ã·ã§ã³ãå®è¡ãããŸããæ¡ä»¶ãçã§ãªããªã£ãåŸãwhile
ã«ãŒãã¯åæ¢ããããã°ã©ã ã¯æ¬¡ã®ã³ãŒãã¹ããŒãã¡ã³ãã«é²ã¿ãŸãã
while counter < 5 {
println!("We loop a while...");
counter = counter + 1;
}
for
ã«ãŒãã¯ãé
ç®ã®ã³ã¬ã¯ã·ã§ã³ãåŠçããããã«ã€ãã¬ãŒã¿ã䜿çšããŠããŸããã«ãŒãã¯ãã³ã¬ã¯ã·ã§ã³å
ã®åã¢ã€ãã ã®åŒæ¬äœã®ã¢ã¯ã·ã§ã³ãç¹°ãè¿ããŸãããã®ã¿ã€ãã®ã«ãŒãã®ç¹°ãè¿ãã¯ãå埩ãšåŒã°ããŸãããã¹ãŠã®å埩ãå®äºãããšãã«ãŒãã¯åæ¢ããŸãã
Rustã§ã¯ãé åããã¯ãã«ãããã·ã¥ããããªã©ãä»»æã®ã³ã¬ã¯ã·ã§ã³ã¿ã€ããå埩åŠçã§ããŸããRustã¯ã€ãã¬ãŒã¿ã䜿çšããŠãã³ã¬ã¯ã·ã§ã³å ã®åã¢ã€ãã ãæåããæåŸãŸã§ç§»åããŸãã
for
ã«ãŒãã¯ã€ãã¬ãŒã¿ãšããŠäžæå€æ°ã䜿çšããŠããŸãã倿°ã¯ã«ãŒãåŒã®éå§æã«æé»çã«å®£èšãããçŸåšã®å€ã¯å埩ããšã«èšå®ãããŸãã
次ã®ã³ãŒãã§ã¯ãã³ã¬ã¯ã·ã§ã³ã¯big_birds
é
åã§ãããã€ãã¬ãŒã¿ãŒã®ååã¯bird
ã§ãã
let big_birds = ["ostrich", "peacock", "stork"];
for bird in big_birds
iter()
ã¡ãœããã䜿çšããŠãã³ã¬ã¯ã·ã§ã³å
ã®ã¢ã€ãã ã«ã¢ã¯ã»ã¹ããŸããfor
åŒã¯çµæã«ã€ãã¬ãŒã¿ã®çŸåšã®å€ããã€ã³ãããiter()
æ¹æ³ãåŒæ¬äœã§ã¯ãã€ãã¬ãŒã¿å€ãæäœã§ããŸãã
let big_birds = ["ostrich", "peacock", "stork"];
for bird in big_birds.iter() {
println!("The {} is a big bird.", bird);
}
åºåã¯æ¬¡ã®ãšããã§ãã
The ostrich is a big bird.
The peacock is a big bird.
The stork is a big bird.
ã€ãã¬ãŒã¿ãäœæãããã1ã€ã®ç°¡åãªæ¹æ³ã¯ãç¯å²è¡šèšã䜿çšããããšã§ãa..b
ãã€ãã¬ãŒã¿ã¯a
å€ããå§ãŸãb
ã1ã¹ããããã€ç¶ããŸãããå€ã䜿çšããŸããb
ã
for number in 0..5 {
println!("{}", number * 2);
}
ãã®ã³ãŒãã¯ã0ã1ã2ã3ãããã³4ã®æ°å€ãnumber
ç¹°ãè¿ãåŠçããŸããã«ãŒãã®ç¹°ãè¿ãããšã«ãå€ã倿°ã«ãã€ã³ãããŸãã
åºåã¯æ¬¡ã®ãšããã§ãã
0
2
4
6
8
ãã®ã³ãŒããå®è¡ããŠããã®RustPlaygroundã§ã«ãŒããæ¢çŽ¢ã§ããŸãã
æŒç¿ïŒã«ãŒãã䜿çšããŠããŒã¿ãå埩åŠçãã
ãã®æŒç¿ã§ã¯ãèªåè»å·¥å Žã®ããã°ã©ã ã倿ŽããŠãã«ãŒãã䜿çšããŠèªåè»ã®æ³šæãå埩åŠçããŸãã
main
颿°ãæŽæ°ããŠã泚æã®å®å
šãªã»ãããåŠçããããã®ã«ãŒãåŒã远å ããŸããã«ãŒãæ§é ã¯ãã³ãŒãã®åé·æ§ãæžããã®ã«åœ¹ç«ã¡ãŸããã³ãŒããç°¡çŽ åããããšã§ã泚æéãç°¡åã«å¢ããããšãã§ããŸãã
ãã®car_factory
颿°ã§ã¯ãç¯å²å€ã®å€ã§ã®å®è¡æã®ãããã¯ãåé¿ããããã«ãå¥ã®ã«ãŒãã远å ããŸãã
課é¡ã¯ããµã³ãã«ã³ãŒãã宿ãããŠãã³ã³ãã€ã«ããŠå®è¡ããããšã§ãã
ãã®æŒç¿ã®ãµã³ãã«ã³ãŒãã§äœæ¥ããã«ã¯ã次ã®2ã€ã®ãªãã·ã§ã³ããããŸãã
ããŒã
ãµã³ãã«ã³ãŒãã§ã
todo!
ãã¯ããæ¢ããŸãããã®ãã¯ãã¯ãå®äºãããæŽæ°ããå¿ èŠãããã³ãŒãã瀺ããŸãã
ååã®æŒç¿ã§ããã°ã©ã ã³ãŒããéããå Žåã¯ããã®æºåãããRustPlaygroundã§ã³ãŒããå床éãããšãã§ããŸãã
å¿ ãããã°ã©ã ãåæ§ç¯ããã³ã³ãã€ã©ãšã©ãŒãªãã§å®è¡ãããããšã確èªããŠãã ããã
ããå€ãã®æ³šæããµããŒãããã«ã¯ãããã°ã©ã ãæŽæ°ããå¿ èŠããããŸããçŸåšã®ã³ãŒãæ§é ã§ã¯ãåé·ã¹ããŒãã¡ã³ãã䜿çšããŠ6ã€ã®æ³šæããµããŒãããŠããŸããåé·æ§ã¯æ±ãã«ãããç¶æããã®ãå°é£ã§ãã
ã«ãŒãåŒã䜿çšããŠã¢ã¯ã·ã§ã³ãç¹°ãè¿ããåæ³šæãäœæããããšã§ãæ§é ãåçŽåã§ããŸããç°¡ç¥åãããã³ãŒãã䜿çšãããšã倿°ã®æ³šæããã°ããäœæã§ããŸãã
main
æ©èœãå逿¬¡ã®æãããã®ã³ãŒããããã¯ã¯ãorder
倿°ãå®çŸ©ããã³èšå®ããèªåè»ã®æ³šæã®car_factory
颿°ãšprintln!
ãã¯ããåŒã³åºããåæ³šæãorders
ããã·ã¥ãããã«æ¿å
¥ããŸãã// Order 6 cars
// - Increment "order" after each request
// - Add each order <K, V> pair to "orders" hash map
// - Call println! to show order details from the hash map
// Initialize order variable
let mut order = 1;
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
2. åé€ãããã¹ããŒãã¡ã³ããæ¬¡ã®ã³ãŒããããã¯ã«çœ®ãæããŸãã
// Start with zero miles
let mut miles = 0;
todo!("Add a loop expression to fulfill orders for 6 cars, initialize `order` variable to 1") {
// Call car_factory to fulfill order
// Add order <K, V> pair to "orders" hash map
// Call println! to show order details from the hash map
car = car_factory(order, miles);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Reset miles for order variety
if miles == 2100 {
miles = 0;
} else {
miles = miles + 700;
}
}
3. ã¢ã¯ã·ã§ã³ãç¹°ãè¿ãã«ãŒãåŒã远å ããŠã6å°ã®è»ã®æ³šæãäœæããŸããorder
1ã«åæåããã倿°ãå¿
èŠã§ãã
4. ããã°ã©ã ããã«ãããŸããã³ãŒãããšã©ãŒãªãã§ã³ã³ãã€ã«ãããããšã確èªããŠãã ããã
次ã®äŸã®ãããªåºåã衚瀺ãããŸãã
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
ããã°ã©ã ã¯çŸåšãã«ãŒãã䜿çšããŠ6å°ã®è»ã®æ³šæãåŠçããŠããŸãã6å°ä»¥äžæ³šæãããšã©ããªããŸããïŒ
main
颿°ã®ã«ãŒãåŒãæŽæ°ããŠã11å°ã®è»ã泚æããŸãã todo!("Update the loop expression to create 11 cars");
2. ããã°ã©ã ãåæ§ç¯ããŸããå®è¡æã«ãããã°ã©ã ã¯ãããã¯ã«ãªããŸãïŒ
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.26s
Running `target/debug/playground`
thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 4', src/main.rs:34:29
ãã®åé¡ã解決ããæ¹æ³ãèŠãŠã¿ãŸãããã
ãã®car_factory
颿°ã§ã¯ãif / elseåŒã䜿çšcolor
ããŠãcolors
é
åã®ã€ã³ããã¯ã¹ã®å€ã確èªããŸãã
// Prevent panic: Check color index for colors array, reset as needed
// Valid color = 1, 2, 3, or 4
// If color > 4, reduce color to valid index
let mut color = order as usize;
if color > 4 {
// color = 5 --> index 1, 6 --> 2, 7 --> 3, 8 --> 4
color = color - 4;
}
colors
é
åã«ã¯4ã€ã®èŠçŽ ãæã¡ããã€æå¹ãªcolor
å Žåã¯ãã€ã³ããã¯ã¹ã®ç¯å²ã¯0ã3ã®æ¡ä»¶åŒããã§ãã¯ããŠããcolor
ç§ãã¡ã¯ããã§ãã¯ããŸããïŒã€ã³ããã¯ã¹ã4ããã倧ããå Žåcolor
ããã®åŸã®é¢æ°ã§4ã«çããã€ã³ããã¯ã¹ãžã®ãšãã«æã
ã®ã€ã³ããã¯ã¹ãè»ã®è²ãå²ãåœãŠãé
åã§ã¯ãã€ã³ããã¯ã¹å€ãã1ãæžç®ããŸãcolor - 1
ãcolor
å€4ã¯colors[3]
ãé
åãšåæ§ã«åŠçãããŸããïŒ
çŸåšã®if / elseåŒã¯ã8å°ä»¥äžã®è»ã泚æãããšãã®å®è¡æã®ãããã¯ãé²ãããã«ããŸãæ©èœããŸãããããã11å°ã®è»ã泚æãããšãããã°ã©ã ã¯9çªç®ã®æ³šæã§ãããã¯ã«ãªããŸããããå ç¢ã«ãªãããã«åŒã調æŽããå¿ èŠããããŸãããã®æ¹åãè¡ãããã«ãå¥ã®ã«ãŒãåŒã䜿çšããŸãã
car_factory
æ©èœãã«ãŒãåŒã§ããã°/ä»ã®æ¡ä»¶æã亀æããŠãã ãããcolor
ã€ã³ããã¯ã¹å€ã4ãã倧ããå Žåã«å®è¡æã®ãããã¯ãé²ãããã«ãæ¬¡ã®æ¬äŒŒã³ãŒãã¹ããŒãã¡ã³ããä¿®æ£ããŠãã ããã// Prevent panic: Check color index, reset as needed
// If color = 1, 2, 3, or 4 - no change needed
// If color > 4, reduce to color to a valid index
let mut color = order as usize;
todo!("Replace `if/else` condition with a loop to prevent run-time panic for color > 4");
ãã³ã
ãã®å Žåãif / elseæ¡ä»¶ããã«ãŒãåŒãžã®å€æŽã¯å®éã«ã¯éåžžã«ç°¡åã§ãã
2. ããã°ã©ã ããã«ãããŸããã³ãŒãããšã©ãŒãªãã§ã³ã³ãã€ã«ãããããšã確èªããŠãã ããã
次ã®åºåã衚瀺ãããŸãã
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
Car order 7: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
Car order 8: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 9: Some(Car { color: "Blue", motor: Automatic, roof: true, age: ("New", 0) })
Car order 10: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 11: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
ãã®ã¢ãžã¥ãŒã«ã§ã¯ãRustã§äœ¿çšã§ããããŸããŸãªã«ãŒãåŒã調ã¹ãããã·ã¥ãããã®æäœæ¹æ³ãçºèŠããŸãããããŒã¿ã¯ãããŒãšå€ã®ãã¢ãšããŠããã·ã¥ãããã«ä¿åãããŸããããã·ã¥ãããã¯æ¡åŒµå¯èœã§ãã
loop
æåã§ããã»ã¹ã忢ãããŸã§ã®åŒã¯ãã¢ã¯ã·ã§ã³ãç¹°ãè¿ããŸããwhile
åŒãã«ãŒãããŠãæ¡ä»¶ãçã§ããéãã¢ã¯ã·ã§ã³ãç¹°ãè¿ãããšãã§ããŸãããã®for
åŒã¯ãããŒã¿åéãå埩åŠçããããã«äœ¿çšãããŸãã
ãã®æŒç¿ã§ã¯ãèªåè»ããã°ã©ã ãæ¡åŒµããŠãç¹°ãè¿ãããã¢ã¯ã·ã§ã³ãã«ãŒããããã¹ãŠã®æ³šæãåŠçããŸãããæ³šæã远跡ããããã«ããã·ã¥ããããå®è£ ããŸããã
ãã®ã©ãŒãã³ã°ãã¹ã®æ¬¡ã®ã¢ãžã¥ãŒã«ã§ã¯ãRustã³ãŒãã§ãšã©ãŒãšé害ãã©ã®ããã«åŠçããããã«ã€ããŠè©³ãã説æããŸãã
ãªã³ã¯: https://docs.microsoft.com/en-us/learn/modules/rust-loop-expressions/