{"id":330462,"date":"2022-03-10T09:00:18","date_gmt":"2022-03-10T09:00:18","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=330462"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=330462","title":{"rendered":"<span>\u041e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442 Rust<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/tf\/u5\/vi\/tfu5vinauktrvp3jxgqwbso1lfe.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/tf\/u5\/vi\/tfu5vinauktrvp3jxgqwbso1lfe.jpeg\" data-blurred=\"true\"\/><\/div>\n<p>  \u041c\u043d\u0435 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u044f\u0437\u044b\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0443\u0436\u0435 \u043d\u0435 \u0442\u0430\u043a \u0441\u0438\u043b\u044c\u043d\u043e, \u0438 \u043d\u0435 \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043c\u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u0430, \u0441\u043a\u043e\u0440\u0435\u0435, \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043c\u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c <em>\u043d\u0435<\/em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442.<\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0440\u0435\u0434\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0441\u0430\u043c\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c: \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 C++, \u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043d\u0430 C, \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u044f\u0437\u044b\u043a \u043f\u043e\u043b\u043e\u043d \u043f\u043e \u0422\u044c\u044e\u0440\u0438\u043d\u0433\u0443 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u0430\u043a\u0438\u043c \u0431\u044b \u043d\u0438 \u0431\u044b\u043b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0432\u044b \u043e\u0431\u0449\u0430\u0435\u0442\u0435\u0441\u044c \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u043e\u0439. \u0412\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0435\u0433\u043e \u043f\u0430\u043c\u044f\u0442\u0438 (\u0438 \u0435\u0451 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e), \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u043a \u043d\u0435\u043c\u0443 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0435\u0439, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<blockquote><p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, <a href=\"https:\/\/github.com\/xoreaxeaxeax\/movfuscator\" rel=\"nofollow noopener noreferrer\">\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e<\/a> \u043b\u0438\u0448\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>mov<\/code>.<\/p><\/blockquote>\n<p>  \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438: \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430. \u042f\u0437\u044b\u043a Java \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0441\u0432\u043e\u0435\u0439 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e\u0441\u0442\u044c\u044e: \u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c \u043e\u043d \u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043e\u0442\u043b\u0430\u0434\u043a\u043e\u043f\u0440\u0438\u0433\u043e\u0434\u043d\u043e\u0441\u0442\u044c (\u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u043d\u0435\u0442, \u0442\u043e \u0435\u0433\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c) \u0438 \u0434\u044e\u0436\u0438\u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u0438 \u00ab\u0432\u044b\u0431\u043e\u0440\u0435 \u044f\u0437\u044b\u043a\u0430\u00bb.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0420\u0430\u0437\u043c\u0435\u0440\u044b \u043b\u0435\u0441\u0430<\/h2>\n<p>  \u041d\u043e \u0437\u0430\u0434\u0443\u043c\u0430\u0439\u0442\u0435\u0441\u044c: \u0438\u0437 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439 \u0432\u0441\u0435\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u043b\u0438\u0448\u044c \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u0430\u044f \u0434\u043e\u043b\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438. \u0418 \u0435\u0449\u0451 \u043c\u0435\u043d\u044c\u0448\u0430\u044f \u0434\u043e\u043b\u044f \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u00ab\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u00bb \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u044d\u0442\u043e\u043c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435. \u0418 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u043e\u043c \u00ab\u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0440\u043e\u0433\u0438\u0445\u00bb \u044f\u0437\u044b\u043a\u043e\u0432 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u044e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u043e\u0438\u0441\u043a, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u00ab\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445\u00bb \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439.<\/p>\n<p>  \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u044d\u0442\u043e, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0441\u043e\u0431\u043b\u0430\u0437\u043d \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0439\u0442\u0438\u043d\u0433 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u043e \u00ab\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u00bb. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 \u043f\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0443, \u043d\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0437\u043d\u043e\u0433\u043b\u0430\u0441\u0438\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u044b.<\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043d\u0430 JavaScript:<\/p>\n<pre><code class=\"javascript\">function foo(i) {   console.log(\"foo\", i); }  function bar() {   console.log(\"bar!\"); }  function main() {   for (i = 0; i &lt; 3; i++) {     foo(i);   }   return;   bar(); }  main();<\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 <code>bar()<\/code> \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u2014 <code>main<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0434\u043e \u0435\u0451 \u0432\u044b\u0437\u043e\u0432\u0430.<\/p>\n<p>  \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 node.js \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"bash\">$ node sample.js foo 0 foo 1 foo 2<\/code><\/pre>\n<p>  \u0422\u043e\u0442 \u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Go \u0442\u043e\u0436\u0435 \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func foo(i int) {   log.Printf(\"foo %d\", i) }  func bar() {   log.Printf(\"bar!\") }  func main() {   for i := 0; i &lt; 3; i++ {     foo(i)   }   return   bar() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go build .\/sample.main $ .\/sample 2022\/02\/06 17:35:55 foo 0 2022\/02\/06 17:35:55 foo 1 2022\/02\/06 17:35:55 foo 2<\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 <code>go vet<\/code> (\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432\u0435 Go) \u043e\u0442\u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"bash\">$ go vet .\/sample.go # command-line-arguments .\/sample.go:18:2: unreachable code<\/code><\/pre>\n<p>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e, <em>\u0441\u0442\u0440\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u044f<\/em>, \u043d\u0430\u0448 \u043a\u043e\u0434 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u043c, \u043e\u043d\u2026 \u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439. \u041e\u043d \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 linter \u0432\u0435\u0436\u043b\u0438\u0432\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442: \u00ab\u0432\u044b \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0438\u043c\u0435\u043b\u0438 \u0432 \u0432\u0438\u0434\u0443? \u0435\u0441\u043b\u0438 \u0434\u0430, \u0442\u043e \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c lint \u0437\u0430\u043c\u043e\u043b\u0447\u0430\u0442\u044c. \u0430 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0448\u0430\u043d\u0441 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0434\u00bb.<\/p>\n<p>  \u0422\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434, \u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Rust, \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u043c\u0443 \u0448\u0443\u043c\u0443:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  fn bar() {     println!(\"bar!\"); }  fn main() {     for i in 0..=2 {         foo(i)     }     return;     bar() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) warning: unreachable expression   --> src\/main.rs:14:5    | 13 |     return;    |     ------ any code following this expression is unreachable 14 |     bar()    |     ^^^^^ unreachable expression    |    = note: `#[warn(unreachable_code)]` on by default  warning: `lox` (bin \"lox\") generated 1 warning     Finished dev [unoptimized + debuginfo] target(s) in 0.15s      Running `target\/debug\/lox` foo 0 foo 1 foo 2<\/code><\/pre>\n<p>  \u041c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u043e\u0434 \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c, \u043d\u043e \u0438 <em>\u043f\u043e\u0447\u0435\u043c\u0443<\/em> \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0435\u0433\u043e \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430 \u043e\u043d\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u0435\u0442. (\u0415\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u043d\u0435 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c <code>#![deny(unreachable_code)]<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u043e <code>main.rs<\/code> \u2014 \u044d\u0442\u043e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 <code>-Werror=something<\/code> \u0432 gcc\/clang).<\/p>\n<h2>\u041e\u0448\u0438\u0431\u0451\u043c\u0441\u044f \u0441\u0435\u0439\u0447\u0430\u0441, \u0443\u0437\u043d\u0430\u0435\u043c \u043e\u0431 \u044d\u0442\u043e\u043c\u2026 \u043a\u043e\u0433\u0434\u0430?<\/h2>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u0431\u0435\u0440\u0451\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>bar<\/code>.<\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u043e\u043d\u0430 \u0432\u0435\u0434\u044c \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0440\u0430\u0437\u0432\u0435 \u044d\u0442\u043e \u043d\u0430 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442?<\/p>\n<pre><code class=\"javascript\">function foo(i) {   console.log(\"foo\", i); }  function main() {   for (i = 0; i &lt; 3; i++) {     foo(i);   }   return;   bar(); }  main();<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ node sample.js foo 0 foo 1 foo 2<\/code><\/pre>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f node.js \u0441\u0447\u0438\u0442\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0438\u043a\u043e\u0433\u043e \u043d\u0435 \u0432\u043e\u043b\u043d\u0443\u0435\u0442 <code>bar<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0435\u0451 <em>\u043d\u0438\u043a\u043e\u0433\u0434\u0430<\/em> \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e Go \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0442\u0438\u0432 \u0438\u0441\u0447\u0435\u0437\u043d\u043e\u0432\u0435\u043d\u0438\u044f <code>bar<\/code>:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func foo(i int) {   log.Printf(\"foo %d\", i) }  func main() {   for i := 0; i &lt; 3; i++ {     foo(i)   }   return   bar() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go  # command-line-arguments .\/sample.go:14:2: undefined: bar<\/code><\/pre>\n<p>  \u2026 \u0438 \u043a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430 \u043a\u0440\u0430\u0442\u043e\u043a.<\/p>\n<p>  \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 Rust \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u0442\u0440\u043e\u0435\u043d:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  fn main() {     for i in 0..=2 {         foo(i)     }     return;     bar() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0425]: cannot find function `bar` in this scope   --> src\/main.rs:10:5    | 10 |     bar()    |     ^^^ not found in this scope  warning: unreachable expression   --> src\/main.rs:10:5    | 9  |     return;    |     ------ any code following this expression is unreachable 10 |     bar()    |     ^^^^^ unreachable expression    |    = note: `#[warn(unreachable_code)]` on by default  For more information about this error, try `rustc --explain E0425`. warning: `lox` (bin \"lox\") generated 1 warning error: could not compile `lox` due to previous error; 1 warning emitted<\/code><\/pre>\n<p>  \u2026 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u0430\u0438\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0431\u044b <code>bar<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 (\u0445\u043e\u0442\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435\u0442), \u0435\u0451 <em>\u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e<\/em> \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 \u0431\u044b \u0438 \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b\u2026 \u043f\u0435\u0440\u0435\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0432\u043e\u0451 \u043c\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0438 Go, \u0438 Rust \u043e\u0442\u0432\u0435\u0440\u0433\u0430\u044e\u0442 \u044d\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043a\u0430\u043a \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 (\u043e\u043d\u0438 \u0432\u044b\u0434\u0430\u044e\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b), \u0434\u0430\u0436\u0435 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e, \u043e\u0442\u043a\u0440\u043e\u0432\u0435\u043d\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u044d\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430.<\/p>\n<p>  \u041d\u043e \u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0435 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u041f\u043e \u0441\u0443\u0442\u0438, node.js \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u043c. \u0412 \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u0435 \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 just-in-time (\u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e), \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u00ab\u043d\u0430 \u043b\u0435\u0442\u0443\u00bb, \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u0434\u0435 \u043d\u043e\u0432\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0438 \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u0438\u043c\u0438 \u043a \u043f\u0440\u0430\u0432\u0434\u0435.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 node.js \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u0430 <code>bar<\/code> \u0434\u043e \u0442\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u043a\u0430 \u0435\u0433\u043e \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0443\u0442 (\u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f, \u0438\u043b\u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u044f\u0442 \u0435\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438 \u0442. \u0434.).<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u043d <em>\u0432\u044b\u0434\u0430\u0441\u0442<\/em> \u043e\u0448\u0438\u0431\u043a\u0443. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<pre><code class=\"javascript\">function foo(i) {   console.log(\"foo\", i); }  function main() {   for (i = 0; i &lt; 3; i++) {     foo(i);   }   \/\/ ? (there used to be a 'return' here)   bar(); }  main();<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ node sample.js foo 0 foo 1 foo 2 \/home\/amos\/bearcove\/lox\/sample.js:10   bar();   ^  ReferenceError: bar is not defined     at main (\/home\/amos\/bearcove\/lox\/sample.js:10:3)     at Object.&lt;anonymous> (\/home\/amos\/bearcove\/lox\/sample.js:13:1)     at Module._compile (node:internal\/modules\/cjs\/loader:1101:14)     at Object.Module._extensions..js (node:internal\/modules\/cjs\/loader:1153:10)     at Module.load (node:internal\/modules\/cjs\/loader:981:32)     at Function.Module._load (node:internal\/modules\/cjs\/loader:822:12)     at Function.executeUserEntryPoint [as runMain] (node:internal\/modules\/run_main:81:12)     at node:internal\/main\/run_main_module:17:47<\/code><\/pre>\n<p>  \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b Go \u0438 Rust \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>main<\/code>. \u0412 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0430\u0434\u0440\u0435\u0441 <code>bar<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u043e\u0442\u044c \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u043a\u043e\u0434\u0430, \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 node.js, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u044b\u043c null \u0438\u043b\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e: \u0438 \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0431\u044b \u043e\u0431 \u044d\u0442\u043e\u043c, \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 \u0431\u044b \u0435\u0451.<\/p>\n<p>  \u0422\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 Go \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func foo(i int) {   log.Printf(\"foo %d\", i) }  type Bar func()  var bar Bar  func main() {   for i := 0; i &lt; 3; i++ {     foo(i)   }   bar() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go build .\/sample.go<\/code><\/pre>\n<p>  \u041d\u043e \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u0442 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438:<\/p>\n<pre><code class=\"go\">$ .\/sample 2022\/02\/06 18:08:06 foo 0 2022\/02\/06 18:08:06 foo 1 2022\/02\/06 18:08:06 foo 2 panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x48756e]  goroutine 1 [running]: main.main()         \/home\/amos\/bearcove\/lox\/sample.go:17 +0x6e<\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043d \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u0442 \u043f\u0430\u043d\u0438\u043a\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c <code>bar<\/code> \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func foo(i int) {   log.Printf(\"foo %d\", i) }  type Bar func()  var bar Bar  \/\/ ? we initialize bar in an `init` function, called implicitly at startup func init() {   bar = func() {     log.Printf(\"bar!\")   } }  func main() {   for i := 0; i &lt; 3; i++ {     foo(i)   }    bar() }<\/code><\/pre>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u0442\u0440\u044e\u043a \u0438 \u0432 Rust:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  fn bar_impl() {     println!(\"bar!\"); }  static BAR: fn() = bar_impl;  fn main() {     for i in 0..=2 {         foo(i)     }     BAR() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox)     Finished dev [unoptimized + debuginfo] target(s) in 0.14s      Running `target\/debug\/lox` foo 0 foo 1 foo 2 bar!<\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0432\u044b\u043b\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0430 \u043d\u0438\u0447\u0442\u043e.<\/p>\n<pre><code class=\"rust\">$ fn foo(i: usize) {     println!(\"foo {}\", i); }  \/\/ ? static BAR: fn();  fn main() {     for i in 0..=2 {         foo(i)     }     BAR() }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error: free static item without body  --> src\/main.rs:5:1   | 5 | static BAR: fn();   | ^^^^^^^^^^^^^^^^-   |                 |   |                 help: provide a definition for the static: `= &lt;expr>;`  error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u0447\u0435\u0441\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u043a \u043d\u0430\u043b\u0438\u0447\u0438\u044f, \u0442\u0430\u043a \u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f <code>bar<\/code>, \u043d\u0443\u0436\u043d\u043e \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0451 \u0442\u0438\u043f \u043d\u0430 <code>Option&lt;fn()><\/code>:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  \/\/            ? static BAR: Option&lt;fn()>;  fn main() {     for i in 0..=2 {         foo(i)     }     BAR() }<\/code><\/pre>\n<p>  \u0418 \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e <em>\u043e\u0431\u044f\u0437\u0430\u043d\u044b<\/em> \u0447\u0442\u043e-\u0442\u043e \u0435\u0439 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c.<\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error: free static item without body  --> src\/main.rs:5:1   | 5 | static BAR: Option&lt;fn()>;   | ^^^^^^^^^^^^^^^^^^^^^^^^-   |                         |   |                         help: provide a definition for the static: `= &lt;expr>;  (other errors omitted)<\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c <code>None<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0431\u044b, \u0435\u0441\u043b\u0438 \u0431\u044b <code>bar<\/code> \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  static BAR: Option&lt;fn()> = None;  fn main() {     for i in 0..=2 {         foo(i)     }     BAR() }<\/code><\/pre>\n<p>  \u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u043c\u0435\u0441\u0442\u0435 \u0432\u044b\u0437\u043e\u0432\u0430:<\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0618]: expected function, found enum variant `BAR`   --> src\/main.rs:11:5    | 5  | static BAR: Option&lt;fn()> = None;    | -------------------------------- `BAR` defined here ... 11 |     BAR()    |     ^^^--    |     |    |     call expression requires function    | help: `BAR` is a unit variant, you need to write it without the parentheses    | 11 -     BAR() 11 +     BAR    |   For more information about this error, try `rustc --explain E0618`. error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c <code>BAR<\/code> \u2014 \u044d\u0442\u043e \u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c, \u0430 <code>Option&lt;fn()><\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 <code>Some(f)<\/code> (\u0433\u0434\u0435 <code>f<\/code> \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c), \u0438\u043b\u0438 <code>None<\/code> (\u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c).<\/p>\n<p>  \u0418\u0442\u0430\u043a, Rust \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0441 \u0443\u0447\u0435\u0441\u0442\u044c \u043e\u0431\u0430 \u0441\u043b\u0443\u0447\u0430\u044f, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>match<\/code>:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  static BAR: Option&lt;fn()> = None;  fn main() {     for i in 0..=2 {         foo(i)     }     match BAR {         Some(f) => f(),         None => println!(\"(no bar implementation found)\"),     } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox)     Finished dev [unoptimized + debuginfo] target(s) in 0.24s      Running `target\/debug\/lox` foo 0 foo 1 foo 2 (no bar implementation found)<\/code><\/pre>\n<p>  \u0418 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0432 <code>BAR<\/code> \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 <code>Some<\/code>:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  static BAR: Option&lt;fn()> = Some({     \/\/ we could define this outside the option, but we don't have to!     \/\/ this is just showing off, but I couldn't resist, because it's fun.     fn bar_impl() {         println!(\"bar!\");     }     \/\/ the last expression of a block (`{}`) is what the block evaluates to     bar_impl });  fn main() {     for i in 0..=2 {         foo(i)     }     match BAR {         Some(f) => f(),         None => println!(\"(no bar implementation found)\"),     } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run     Finished dev [unoptimized + debuginfo] target(s) in 0.00s      Running `target\/debug\/lox` foo 0 foo 1 foo 2 bar!<\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043a \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u043e\u0432:<\/p>\n<ul>\n<li>JavaScript (\u0437\u0434\u0435\u0441\u044c \u0447\u0435\u0440\u0435\u0437 node.js) \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435 \u0432\u043e\u043b\u043d\u0443\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 <code>bar()<\/code>, \u043f\u043e\u043a\u0430 \u0435\u0451 \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0443\u0442.<\/li>\n<li>Go \u0432\u043e\u043b\u043d\u0443\u0435\u0442, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u043e \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e, \u0438 \u0437\u0430\u043f\u0430\u043d\u0438\u043a\u0443\u0435\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/li>\n<li>Rust \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442.<\/li>\n<\/ul>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0431\u0435\u0437\u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 JavaScript \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u043c: \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 Go \u0438 Rust. \u0418 \u0445\u043e\u0442\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435 \u043d\u0435\u0442 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 <code>bar<\/code>, \u043e\u043d\u043e <em>\u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e<\/em> \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"javascript\">function foo(i) {   console.log(\"foo\", i); }  eval(   `mruhgr4hgx&amp;C&amp;.\/&amp;CD&amp;iutyurk4rum.(hgx'(\/A`     .split(\"\")     .map((c) => String.fromCharCode(c.charCodeAt(0) - 6))     .join(\"\"), );  function main() {   for (i = 0; i &lt; 3; i++) {     foo(i);   }   bar(); }  main();<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ node sample.js foo 0 foo 1 foo 2 bar!<\/code><\/pre>\n<p>  \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f Rust, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c: <em>\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439<\/em> Rust \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u044d\u0442\u043e\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043c \u0441\u0435\u0431\u0435 \u043f\u0438\u0441\u0430\u0442\u044c <code>\u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439<\/code> \u043a\u043e\u0434, <em>\u043d\u0435\u043e\u0442\u044a\u0435\u043c\u043b\u0435\u043c\u0443\u044e<\/em> \u0447\u0430\u0441\u0442\u044c Rust, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043f\u043e\u0432\u0435\u0440\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 C \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0432\u044b\u043b\u0435\u0442:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  \/\/ initialize BAR with some garbage static BAR: fn() = unsafe { std::mem::transmute(&amp;()) };  fn main() {     for i in 0..=2 {         foo(i)     }     BAR(); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0080]: it is undefined behavior to use this value  --> src\/main.rs:5:1   | 5 | static BAR: fn() = unsafe { std::mem::transmute(&amp;()) };   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc4, but expected a function pointer   |   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.   = note: the raw bytes of the constant (size: 8, align: 8) {               \u257e\u2500\u2500\u2500\u2500\u2500\u2500\u2500alloc4\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u257c                         \u2502 \u257e\u2500\u2500\u2500\u2500\u2500\u2500\u257c           }  For more information about this error, try `rustc --explain E0080`. error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u0425\u043c, \u043d\u0435\u0442, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b \u044d\u0442\u043e.<\/p>\n<p>  \u041b\u0430\u0434\u043d\u043e, \u0442\u043e\u0433\u0434\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"rust\">fn foo(i: usize) {     println!(\"foo {}\", i); }  const BAR: *const () = std::ptr::null();  fn main() {     for i in 0..=2 {         foo(i)     }      let bar: fn() = unsafe { std::mem::transmute(BAR) };     bar(); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox)     Finished dev [unoptimized + debuginfo] target(s) in 0.13s      Running `target\/debug\/lox` foo 0 foo 1 foo 2 zsh: segmentation fault (core dumped)  cargo run<\/code><\/pre>\n<p>  \u0412\u043e\u0442. \u041d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u0442\u0440\u0443\u0434\u0438\u0442\u044c\u0441\u044f, \u043d\u043e \u043c\u044b \u0435\u0433\u043e \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c.<\/p>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0438\u0437 \u044d\u0442\u0438\u0445 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 JavaScript \u0441\u0430\u043c\u044b\u0439 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 (\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0442. \u0434.), Rust \u2014 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0440\u043e\u0433\u0438\u0439 (\u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0438\u0441\u0430\u044e\u0449\u0438\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u043c Rust), \u0430 Go \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0433\u0434\u0435-\u0442\u043e \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435.<\/p>\n<h2>\u0415\u0449\u0451 \u043e \u0442\u0438\u043f\u0430\u0445<\/h2>\n<p>  \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0451\u0442\u043a\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0442\u043e\u043c, \u043a\u0430\u043a \u044d\u0442\u0438 \u0442\u0440\u0438 \u044f\u0437\u044b\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438.<\/p>\n<p>  \u0427\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e \u043b\u0435\u0433\u043a\u043e (\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u0430\u0436\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043b\u0435\u0433\u043a\u043e) \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e JavaScript, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0443\u044e \u00ab\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u00bb \u0434\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>add<\/code> \u0441 \u043b\u0451\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0438 \u0441\u043b\u043e\u0436\u0438\u0442 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430, \u0438 \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0438\u0440\u0443\u0435\u0442 \u0434\u0432\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">function add(a, b) {   return a + b; }  function main() {   console.log(add(1, 2));   console.log(add(\"foo\", \"bar\")); }  main();<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ node sample.js 3 foobar<\/code><\/pre>\n<p>  \u041d\u0430 Go \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u0438\u043f.<\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0447\u0438\u0441\u043b\u0430\u043c\u0438:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func add(a int, b int) int {   return a + b }  func main() {   log.Printf(\"%v\", add(1, 2)) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/06 19:01:55 3<\/code><\/pre>\n<p>  \u0418 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438:<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func add(a string, b string) string {   return a + b }  func main() {   log.Printf(\"%v\", add(\"foo\", \"bar\")) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/06 19:02:25 foobar<\/code><\/pre>\n<p>  \u041d\u043e \u043d\u0435 \u0441 \u0442\u0435\u043c\u0438 \u0438 \u044d\u0442\u0438\u043c\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u0418\u043b\u0438 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e?<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func add(a interface{}, b interface{}) interface{} {   if a, ok := a.(int); ok {     if b, ok := b.(int); ok {       return a + b     }   }    if a, ok := a.(string); ok {     if b, ok := b.(string); ok {       return a + b     }   }    panic(\"incompatible types\") }  func main() {   log.Printf(\"%v\", add(1, 2))   log.Printf(\"%v\", add(\"foo\", \"bar\")) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/06 19:05:11 3 2022\/02\/06 19:05:11 foobar<\/code><\/pre>\n<p>  \u041d\u043e\u2026 \u044d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e. <code>add(1, \"foo\")<\/code> \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0434\u0430\u0441\u0442 \u043f\u0430\u043d\u0438\u043a\u0443 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0432 Go 1.18 beta \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c?..<\/p>\n<pre><code class=\"go\">package main  import \"log\"  func add[T int64 | string](a T, b T) T {   return a + b }  func main() {   log.Printf(\"%v\", add(1, 2))   log.Printf(\"%v\", add(\"foo\", \"bar\")) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/main.go .\/main.go:10:22: int does not implement int64|string<\/code><\/pre>\n<p>  \u041f\u043e\u043d\u044f\u0442\u043d\u043e. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 <a href=\"https:\/\/go.googlesource.com\/proposal\/+\/refs\/heads\/master\/design\/43651-type-parameters.md#operators\" rel=\"nofollow noopener noreferrer\">type parameters proposal<\/a>. \u041e\u0439. \u041d\u0443 \u043b\u0430\u0434\u043d\u043e.<\/p>\n<pre><code class=\"go\">package main  import \"log\"  type Addable interface {   ~int | ~int8 | ~int16 | ~int32 | ~int64 |     ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |     ~float32 | ~float64 | ~complex64 | ~complex128 |     ~string }  func add[T Addable](a T, b T) T {   return a + b }  func main() {   log.Printf(\"%v\", add(1, 2))   log.Printf(\"%v\", add(\"foo\", \"bar\")) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/main.go 2022\/02\/06 19:12:11 3 2022\/02\/06 19:12:11 foobar<\/code><\/pre>\n<p>  \u041d\u0443 \u0434\u0430, \u044d\u0442\u043e\u2026 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e \u043c\u044b \u0436\u0435 \u043d\u0435 \u0432\u044b\u0440\u0430\u0436\u0430\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u0430, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u044f \u0432\u0441\u0435 \u0442\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c. \u0414\u0443\u043c\u0430\u044e, \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u0430\u0445\u043e\u0447\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>+<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u0418\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u044f\u0437\u044b\u043a <code>int128<\/code> \/ <code>uint128<\/code>.<\/p>\n<p>  \u041d\u0443 \u0434\u0430 \u043b\u0430\u0434\u043d\u043e.<\/p>\n<p>  \u0427\u0442\u043e \u0436\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430\u2026 \u0442\u043e \u043e\u043d \u0432\u0435\u0434\u044c \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043f\u0440\u043e\u044f\u0432\u0438\u0442 \u0441\u0435\u0431\u044f \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u043e? \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043b\u043e\u0445\u043e \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u0440\u043e\u043f\u0430\u0433\u0430\u043d\u0434\u0430 Rust, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0442\u043e\u0447\u043d\u043e\u2026<\/p>\n<pre><code class=\"rust\">use std::ops::Add;  fn add&lt;T>(a: T, b: T) -> T::Output where     T: Add&lt;T>, {     a + b }  fn main() {     dbg!(add(1, 2));     dbg!(add(\"foo\", \"bar\")); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0277]: cannot add `&amp;str` to `&amp;str`   --> src\/main.rs:12:10    | 12 |     dbg!(add(\"foo\", \"bar\"));    |          ^^^ no implementation for `&amp;str + &amp;str`    |    = help: the trait `Add` is not implemented for `&amp;str` note: required by a bound in `add`   --> src\/main.rs:5:8    | 3  | fn add&lt;T>(a: T, b: T) -> T::Output    |    --- required by a bound in this 4  | where 5  |     T: Add&lt;T>,    |        ^^^^^^ required by this bound in `add`  For more information about this error, try `rustc --explain E0277`. error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u0425\u043c.<\/p>\n<p>  \u0412 \u0441\u043c\u044b\u0441\u043b\u0435, \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0442\u0430\u043a\u043e\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u0418 \u043b\u0438\u0447\u043d\u043e \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f: \u0432\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044f \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e \u00ab\u043b\u044e\u0431\u043e\u0439 \u0442\u0438\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u00bb, \u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u044e \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u041c\u044b \u0434\u0430\u0436\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0447\u0442\u043e\u0431\u044b <code>T + T<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u0442\u0438\u043f, \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u0441\u044f <code>T<\/code>! \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e <code>&lt;T as Add&lt;T>>::Output<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c.<\/p>\n<p>  \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0430\u044f: \u043e\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u0443 \u043f\u0440\u043e\u0441\u044c\u0431\u0443 \u043d\u0435\u043b\u044c\u0437\u044f \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u0442\u044c\u2026 \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u041e\u043d\u0430 \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442, \u043f\u043e\u0447\u0435\u043c\u0443 <code>Add<\/code> \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f <code>&amp;str<\/code> \u0438 <code>&amp;str<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u043e\u043c\u043e\u0433\u0443. <code>&amp;str<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e slice \u0441\u0442\u0440\u043e\u043a\u0438: \u043e\u043d \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u043d\u043e \u043d\u0435 \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0441\u0430\u043c\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c \u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code class=\"rust\">fn add&lt;T>(_: T, _: T) -> T {     todo!(); }  fn main() {     dbg!(add(1, 2));     dbg!(add(\"foo\", \"bar\")); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo build --quiet $ objdump -s -j .rodata .\/target\/debug\/lox | grep -B 3 -A 3 -E 'foo|bar'  3c0d0 03000000 00000000 02000000 00000000  ................  3c0e0 00000000 00000000 02000000 00000000  ................  3c0f0 00000000 00000000 20000000 04000000  ........ .......                                                      ?  3c100 03000000 00000000 62617266 6f6f6164  ........barfooad  3c110 64282266 6f6f222c 20226261 7222296e  d(\"foo\", \"bar\")n  3c120 6f742079 65742069 6d706c65 6d656e74  ot yet implement  3c130 65647372 632f6d61 696e2e72 73000000  edsrc\/main.rs...  3c140 01000000 00000000 00000000 00000000  ................<\/code><\/pre>\n<p>  \u2026 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b: \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>\"foo\"<\/code> \u2014 \u044d\u0442\u043e <code>&amp;'static str<\/code>.<\/p>\n<p>  \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u00abfoo\u00bb \u0438 \u00abbar\u00bb, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 <code>String<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0434\u0435\u043b\u0438\u0442 \u043f\u0430\u043c\u044f\u0442\u044c \u0432 \u043a\u0443\u0447\u0435. \u0418 <code>String<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Deref&lt;Target=str><\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0451, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 <code>&amp;str<\/code>, \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u0441 <code>String<\/code>.<\/p>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>&amp;str + &amp;str<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>String + &amp;str<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/doc.rust-lang.org\/stable\/std\/string\/struct.String.html#impl-Add%3C%26%27_%20str%3E\" rel=\"nofollow noopener noreferrer\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e<\/a>, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u043c\u0443:<\/p>\n<blockquote><p><code>impl&lt;'_> Add&lt;&amp;'_ str> for String<\/code><\/p>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>+<\/code> \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0430\u0446\u0438\u0438 \u0434\u0432\u0443\u0445 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<p>  \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>String<\/code> \u0432 \u043b\u0435\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u0431\u0443\u0444\u0435\u0440 (\u0441 \u0435\u0433\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e). \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u0443\u044e <code>String<\/code> \u0438 \u043d\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u043b\u043e \u0431\u044b \u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 <em>n<\/em>-\u0431\u0430\u0439\u0442\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0430\u0446\u0438\u0435\u0439.<\/p>\n<p>  \u0421\u0442\u0440\u043e\u043a\u0430 \u0441\u043f\u0440\u0430\u0432\u0430 \u043b\u0438\u0448\u044c \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u0443\u0435\u0442\u0441\u044f; \u0435\u0451 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0443\u044e <code>String<\/code>.<\/p><\/blockquote>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 <code>String<\/code> \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>.to_string()<\/code>:<\/p>\n<pre><code class=\"rust\">use std::ops::Add;  fn add&lt;T>(a: T, b: T) -> T::Output where     T: Add&lt;T>, {     a + b }  fn main() {     dbg!(add(1, 2));     dbg!(add(\"foo\".to_string(), \"bar\".to_string())); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0277]: cannot add `String` to `String`   --> src\/main.rs:12:10    | 12 |     dbg!(add(\"foo\".to_string(), \"bar\".to_string()));    |          ^^^ no implementation for `String + String`    |    = help: the trait `Add` is not implemented for `String` note: required by a bound in `add`   --> src\/main.rs:5:8    | 3  | fn add&lt;T>(a: T, b: T) -> T::Output    |    --- required by a bound in this 4  | where 5  |     T: Add&lt;T>,    |        ^^^^^^ required by this bound in `add`  error[E0277]: cannot add `String` to `String`   --> src\/main.rs:12:10    | 12 |     dbg!(add(\"foo\".to_string(), \"bar\".to_string()));    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `String + String`    |    = help: the trait `Add` is not implemented for `String`  For more information about this error, try `rustc --explain E0277`. error: could not compile `lox` due to 2 previous errors<\/code><\/pre>\n<p>  \u2026 \u0442\u043e \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0435\u0442 <code>impl Add&lt;String, Output = String> for String<\/code>.<\/p>\n<p>  \u0422\u043e\u043b\u044c\u043a\u043e <code>impl Add&lt;&amp;str, Output = String> for String<\/code>. \u041d\u0430\u043c \u043d\u0435 <em>\u043d\u0443\u0436\u043d\u043e<\/em> \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u044b\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c <code>+<\/code>: \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"rust\">use std::ops::Add;  fn add&lt;A, B>(a: A, b: B) -> A::Output where     A: Add&lt;B>, {     a + b }  fn main() {     dbg!(add(1, 2));     dbg!(add(\"foo\".to_string(), \"bar\")); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox)     Finished dev [unoptimized + debuginfo] target(s) in 0.21s      Running `target\/debug\/lox` [src\/main.rs:11] add(1, 2) = 3 [src\/main.rs:12] add(\"foo\".to_string(), \"bar\") = \"foobar\"<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u0435\u0442 \u0441\u0435\u0431\u044f \u0437\u0434\u0435\u0441\u044c Rust? \u042d\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f.<\/p>\n<p>  \u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0432\u0430\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432), \u0432\u0430\u043c <em>\u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f<\/em> \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0418 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0430\u0441 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0441\u0430\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>Add<\/code>.<\/p>\n<pre><code class=\"rust\">fn main() {     \/\/ I know `to_string` allocates, it's not hidden behind `+`.     \/\/ the `+` may reallocate (to grow the `String`).     let foobar = \"foo\".to_string() + \"bar\";     dbg!(&amp;foobar); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">fn main() {     let foo: String = \"foo\".into();     let bar: String = \"bar\".into();      \/\/ ? this doesn't build:     \/\/ the right-hand-side cannot be a `String`, it has to be a string slice,     \/\/ e.g. `&amp;str`     let foobar = foo + bar;     dbg!(&amp;foobar); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">fn main() {     let foo: String = \"foo\".into();     let bar: String = \"bar\".into();      \/\/ this builds fine!     let foobar = foo + &amp;bar;     dbg!(&amp;foobar); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">fn main() {     let foo: String = \"foo\".into();     let bar: String = \"bar\".into();      let foobar = foo + &amp;bar;     dbg!(&amp;foobar);      \/\/ ? this doesn't build!     \/\/ `foo` was moved during the first addition (it was reused to store the     \/\/ result of concatenating the two strings)     let foobar = foo + &amp;bar;     dbg!(&amp;foobar); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"rust\">fn main() {     let foo: String = \"foo\".into();     let bar: String = \"bar\".into();      let foobar = foo.clone() + &amp;bar;     dbg!(&amp;foobar);      \/\/ this builds fine! we've cloned foo in the previous addition, which     \/\/ allocates. again, nothing is hidden in the implementation of `+`.     let foobar = foo + &amp;bar;     dbg!(&amp;foobar); }<\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u0430\u0441\u043f\u0435\u043a\u0442 Rust \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 \u043e\u0442 \u043d\u0435\u0433\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0414\u0430\u0436\u0435 \u0442\u0435\u0445, \u043a\u0442\u043e \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043b\u044e\u0431\u0438\u0442 Rust \u043f\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0443 \u0438\u043d\u044b\u0445 \u043f\u0440\u0438\u0447\u0438\u043d. \u0427\u0430\u0441\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u044f\u0442, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 Rust \u0435\u0441\u0442\u044c \u044f\u0437\u044b\u043a \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u044c\u0441\u044f \u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043f\u0430\u043c\u044f\u0442\u0438), \u043d\u043e \u0435\u0433\u043e \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438.<\/p>\n<p>  \u0427\u0442\u043e \u0436, \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0436\u0434\u0430\u0442\u044c.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0430\u0441\u043f\u0435\u043a\u0442 \u0434\u0435\u043b\u0430\u0435\u0442 Rust \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0415\u0433\u043e \u043e\u0442\u0442\u043e\u0447\u0435\u043d\u043d\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044e, \u0441\u0440\u043e\u043a\u0430\u043c \u0436\u0438\u0437\u043d\u0438 \u0438 \u0442. \u0434. \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0433\u0438\u0435 \u0438\u0437 \u0435\u0433\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.<\/p>\n<h2>\u041f\u043e\u0442\u0435\u0440\u044f \u043f\u043e\u0442\u043e\u043a\u0430<\/h2>\n<p>  \u0418\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u044b\u0439 \u043a\u043e\u0434\/\u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0438 \u0442\u0438\u043f\u044b, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438!<\/p>\n<p>  \u041a\u043e\u0434 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u00ab\u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u00bb, \u0435\u0441\u043b\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432.<\/p>\n<p>  JavaScript \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">function sleep(ms) {   return new Promise((resolve, _reject) => setTimeout(resolve, ms)); }  async function doWork(name) {   for (let i = 0; i &lt; 30; i++) {     await sleep(Math.random() * 40);     process.stdout.write(name);   } }  Promise.all([\"a\", \"b\"].map(doWork)).then(() => {   process.stdout.write(\"\\n\"); });<\/code><\/pre>\n<p>  \u0418 \u043e\u043d \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 node.js:<\/p>\n<pre><code class=\"bash\">$ node sample.js abbaabbababaababbababbaabaabaababaabbabababaaababbbaababbabb<\/code><\/pre>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0438\u043c \u0437\u0434\u0435\u0441\u044c, \u0447\u0442\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u00aba\u00bb \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u00abb\u00bb. \u041d\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e: \u043e\u043d\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f <em>\u0432 \u043e\u0434\u043d\u043e \u0432\u0440\u0435\u043c\u044f<\/em>, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u044e\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0448\u0430\u0433\u0438 \u043e\u0434\u043d\u0430 \u0437\u0430 \u0434\u0440\u0443\u0433\u043e\u0439, \u0438 \u0434\u043b\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432\u0440\u044f\u0434 \u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u0430.<\/p>\n<p>  \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c node.js \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u0438\u0445 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f: \u0430\u0433\u0430, \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435! \u041e\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u00ab\u043f\u0440\u0438\u0432\u0435\u0442\u00bb, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u00ab\u043f\u0440\u0438\u0432\u0435\u0442\u00bb, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c TLS handshake.<\/p>\n<p>  \u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u0432 \u043d\u0451\u043c \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a, \u0432\u0442\u043e\u0440\u043e\u0439, \u0442\u0440\u0435\u0442\u0438\u0439 \u0438 \u0442. \u0434. \u2014 \u0432\u0441\u0451 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c. \u0410 \u0437\u0430\u0442\u0435\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u043c\u0443 \u0442\u0435\u043b\u043e, \u043f\u043e \u043b\u043e\u0436\u0435\u0447\u043a\u0435 \u0437\u0430 \u0440\u0430\u0437, \u0433\u0434\u0435 \u043b\u043e\u0436\u043a\u0438 \u2014 \u044d\u0442\u043e \u0431\u0443\u0444\u0435\u0440\u044b.<\/p>\n<p>  \u0423 node.js \u0435\u0441\u0442\u044c <a href=\"https:\/\/nodejs.org\/dist\/latest\/docs\/api\/worker_threads.html\" rel=\"nofollow noopener noreferrer\">\u043f\u043e\u0442\u043e\u043a\u0438<\/a>, \u043d\u043e \u0438\u0445 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432; \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0432 \u0444\u043e\u043d\u0435 \u0437\u0430\u0434\u0430\u0447, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430, \u0430 \u043d\u0435 \u0434\u043b\u044f \u0432\u0435\u0449\u0435\u0439, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0445 \u0432\u0432\u043e\u0434\u043e\u043c-\u0432\u044b\u0432\u043e\u0434\u043e\u043c.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a Go, \u043c\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<pre><code class=\"go\">package main  import (   \"fmt\"   \"math\/rand\"   \"sync\"   \"time\" )  func doWork(name string) {   for i := 0; i &lt; 30; i++ {     time.Sleep(time.Duration(rand.Intn(40)) * time.Millisecond)     fmt.Printf(\"%v\", name)   } }  func main() {   var wg sync.WaitGroup    for name := range []string{\"a\", \"b\"} {     wg.Add(1)     go func() {       defer wg.Done()       doWork(name)     }()   }    wg.Wait()   fmt.Printf(\"\\n\") }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go  # command-line-arguments .\/sample.go:24:10: cannot use name (type int) as type string in argument to doWork<\/code><\/pre>\n<p>  \u0425\u0430-\u0445\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u00abfor range\u00bb \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0438 \u043f\u0435\u0440\u0432\u043e\u0435 \u2014 \u044d\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0432 \u043a <code>_<\/code>.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0435\u0449\u0451 \u0440\u0430\u0437:<\/p>\n<pre><code class=\"go\">\/\/ omitted: package, imports, func doWork  func main() {   var wg sync.WaitGroup    for _, name := range []string{\"a\", \"b\"} {     wg.Add(1)     go func() {       defer wg.Done()       doWork(name)     }()   }    wg.Wait()   fmt.Printf(\"\\n\") }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb<\/code><\/pre>\n<p>  \u041e\u0439-\u0451\u0439, \u043e\u043f\u044f\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b\u043e\u0441\u044c. \u041d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0432\u044b\u0434\u0430\u0451\u0442 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0439, \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u2026<\/p>\n<p>  \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c <code>go vet<\/code>?<\/p>\n<pre><code class=\"bash\">$ go vet .\/sample.go # command-line-arguments .\/sample.go:24:11: loop variable name captured by func literal<\/code><\/pre>\n<p>  \u0410\u0433\u0430, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e! \u0412 Go \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u0430\u043a.<\/p>\n<pre><code class=\"go\">func main() {   var wg sync.WaitGroup    for _, name := range []string{\"a\", \"b\"} {     wg.Add(1)     name := name     go func() {       defer wg.Done()       doWork(name)     }()   }    wg.Wait()   fmt.Printf(\"\\n\") }<\/code><\/pre>\n<p>  \u0412\u043e\u0442!<\/p>\n<p>  \u041a\u0430\u043a \u0431\u044b \u0442\u043e \u043d\u0438 \u0431\u044b\u043b\u043e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439:<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go babbababaabbbabbbababbaabbbaabbabababbababbabaababbaaaaaaaaa<\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043e\u0431\u0435\u0438\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0439 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043d\u0435\u0442. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0442\u043e\u043a \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c\u044b\u0445 \u00aba\u00bb \u0438 \u00abb\u00bb. \u0414\u0432\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u00abdoWork\u00bb \u0442\u043e\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 Go \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u041d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0435\u0441\u0442\u044c: \u0432 Go \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043e\u0442\u043e\u043a\u0438.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0441\u043d\u043e\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 node.js, \u043d\u043e \u043f\u043e\u0434 <code>strace<\/code>, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>write<\/code>, \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0434\u043e 5, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u043e\u0434 \u0431\u044b\u043b \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435\u2026<\/p>\n<pre><code class=\"bash\">\u276f strace -f -e write node .\/sample.js > \/dev\/null write(5, \"*\", 1)                        = 1 strace: Process 1396685 attached strace: Process 1396686 attached strace: Process 1396687 attached strace: Process 1396688 attached strace: Process 1396689 attached [pid 1396684] write(16, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 strace: Process 1396690 attached [pid 1396684] write(1, \"b\", 1)          = 1 [pid 1396684] write(1, \"b\", 1)          = 1 [pid 1396684] write(1, \"a\", 1)          = 1 [pid 1396684] write(1, \"a\", 1)          = 1 [pid 1396684] write(1, \"b\", 1)          = 1 [pid 1396684] write(1, \"a\", 1)          = 1 [pid 1396684] write(1, \"b\", 1)          = 1 [pid 1396684] write(1, \"a\", 1)          = 1 [pid 1396684] write(1, \"a\", 1)          = 1 [pid 1396684] write(1, \"b\", 1)          = 1 [pid 1396684] write(1, \"\\n\", 1)         = 1 [pid 1396684] write(12, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1396689] +++ exited with 0 +++ [pid 1396688] +++ exited with 0 +++ [pid 1396687] +++ exited with 0 +++ [pid 1396686] +++ exited with 0 +++ [pid 1396685] +++ exited with 0 +++ [pid 1396690] +++ exited with 0 +++ +++ exited with 0 +++<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><code>strace<\/code> \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445, \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c.<\/p>\n<p>  \u041e\u043f\u0446\u0438\u044f <code>-f<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u00abfollow forks\u00bb, \u043e\u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u00abpid\u00bb, \u0447\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u00abprocess identifier\u00bb, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 Linux (\u0433\u0434\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u044d\u0442\u043e\u0442 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442), \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0442\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u044d\u0442\u0438 pid \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f tid (thread identifier).<\/p><\/blockquote>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0438 \u00aba\u00bb, \u0438 \u00abb\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c (PID 1396684).<\/p>\n<p>  \u041d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043d\u0430 Go:<\/p>\n<pre><code class=\"bash\">$ go build .\/sample.go &amp;&amp; strace -f -e write .\/sample > \/dev\/null strace: Process 1398810 attached strace: Process 1398811 attached strace: Process 1398812 attached strace: Process 1398813 attached [pid 1398813] write(1, \"b\", 1)          = 1 [pid 1398809] write(1, \"a\", 1)          = 1 [pid 1398813] write(1, \"b\", 1)          = 1 [pid 1398813] write(5, \"\\0\", 1)         = 1 [pid 1398809] write(1, \"b\", 1)          = 1 [pid 1398813] write(1, \"a\", 1)          = 1 [pid 1398809] write(1, \"b\", 1)          = 1 [pid 1398813] write(1, \"a\", 1)          = 1 [pid 1398813] write(5, \"\\0\", 1)         = 1 [pid 1398809] write(1, \"a\", 1)          = 1 [pid 1398813] write(1, \"b\", 1)          = 1 [pid 1398809] write(1, \"a\", 1)          = 1 [pid 1398809] write(1, \"\\n\", 1)         = 1 [pid 1398813] +++ exited with 0 +++ [pid 1398812] +++ exited with 0 +++ [pid 1398811] +++ exited with 0 +++ [pid 1398810] +++ exited with 0 +++ +++ exited with 0 +++<\/code><\/pre>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u00aba\u00bb \u0438 \u00abb\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e PID 1398809 \u0438 1398813, \u0438 \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a\u0442\u043e-\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u0431\u0430\u0439\u0442 (<code>\\0<\/code>); \u043f\u043e \u043c\u043e\u0435\u043c\u0443 \u043c\u043d\u0435\u043d\u0438\u044e, \u044d\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0442\u043e\u0447\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c.<\/p>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c Go \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a:<\/p>\n<pre><code class=\"bash\">$ go build .\/sample.go &amp;&amp; GOMAXPROCS=1 strace -f -e write .\/sample > \/dev\/null strace: Process 1401117 attached strace: Process 1401118 attached strace: Process 1401119 attached [pid 1401116] write(1, \"b\", 1)          = 1 [pid 1401116] write(1, \"a\", 1)          = 1 [pid 1401116] write(1, \"b\", 1)          = 1 [pid 1401116] write(1, \"b\", 1)          = 1 [pid 1401116] write(1, \"a\", 1)          = 1 [pid 1401119] write(1, \"b\", 1)          = 1 [pid 1401119] write(1, \"a\", 1)          = 1 [pid 1401119] write(1, \"b\", 1)          = 1 [pid 1401116] write(1, \"a\", 1)          = 1 [pid 1401116] write(1, \"a\", 1)          = 1 [pid 1401116] write(1, \"\\n\", 1)         = 1 [pid 1401119] +++ exited with 0 +++ [pid 1401118] +++ exited with 0 +++ [pid 1401117] +++ exited with 0 +++ +++ exited with 0 +++<\/code><\/pre>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430!<\/p>\n<p>  \u0425\u043e\u0442\u044f \u043f\u043e\u0441\u0442\u043e\u0439\u0442\u0435-\u043a\u0430, \u043d\u0435\u0442! \u0427\u0442\u043e?<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a <a href=\"https:\/\/pkg.go.dev\/runtime\" rel=\"nofollow noopener noreferrer\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>:<\/p>\n<blockquote><p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f GOMAXPROCS \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u0434 Go \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f. \u041d\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u043e\u0442 \u043b\u0438\u0446\u0430 \u043a\u043e\u0434\u0430 Go; \u043e\u043d\u0438 \u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0438 GOMAXPROCS. \u0424\u0443\u043d\u043a\u0446\u0438\u044f GOMAXPROCS \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435.<\/p><\/blockquote>\n<p>  \u041e-\u043e-\u043e, \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, <code>nanosleep<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c.<\/p>\n<p>  \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f Rust, \u0442\u043e \u043c\u044b \u0442\u043e\u0447\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438:<\/p>\n<pre><code class=\"rust\">use std::{     io::{stdout, Write},     time::Duration, };  use rand::Rng;  fn do_work(name: String) {     let mut rng = rand::thread_rng();     for _ in 0..40 {         std::thread::sleep(Duration::from_millis(rng.gen_range(0..=30)));         print!(\"{}\", name);         stdout().flush().ok();     } }  fn main() {     let a = std::thread::spawn(|| do_work(\"a\".into()));     let b = std::thread::spawn(|| do_work(\"b\".into()));     a.join().unwrap();     b.join().unwrap();     println!(); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet babbabbabaabababbaaaabbabbabbababaaababbabababbbabbababbababababababaa<\/code><\/pre>\n<p>  \u0412\u044b\u0432\u043e\u0434 <code>strace<\/code> \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043c\u044b \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u0438 \u0431\u044b (\u043c\u044b \u0441\u043d\u043e\u0432\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0434\u043e \u043f\u044f\u0442\u0438 \u0440\u0430\u0434\u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0447\u0442\u0435\u043d\u0438\u044f):<\/p>\n<pre><code class=\"bash\">$ cargo build --quiet &amp;&amp; strace -e write -f .\/target\/debug\/lox > \/dev\/null strace: Process 1408066 attached strace: Process 1408067 attached [pid 1408066] write(1, \"a\", 1)          = 1 [pid 1408067] write(1, \"b\", 1)          = 1 [pid 1408066] write(1, \"a\", 1)          = 1 [pid 1408067] write(1, \"b\", 1)          = 1 [pid 1408067] write(1, \"b\", 1)          = 1 [pid 1408067] write(1, \"b\", 1)          = 1 [pid 1408066] write(1, \"a\", 1)          = 1 [pid 1408067] write(1, \"b\", 1)          = 1 [pid 1408067] +++ exited with 0 +++ [pid 1408066] write(1, \"a\", 1)          = 1 [pid 1408066] write(1, \"a\", 1)          = 1 [pid 1408066] +++ exited with 0 +++ write(1, \"\\n\", 1)                       = 1 +++ exited with 0 +++<\/code><\/pre>\n<p>  \u00aba\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f PID 1408066, \u0430 \u00abb\u00bb \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f PID 1408067.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441 async, \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u0440\u0435\u0439\u0442\u0430 <a href=\"https:\/\/lib.rs\/crates\/tokio\" rel=\"nofollow noopener noreferrer\">tokio<\/a>:<\/p>\n<pre><code class=\"rust\">use rand::Rng; use std::{     io::{stdout, Write},     time::Duration, }; use tokio::{spawn, time::sleep};  async fn do_work(name: String) {     for _ in 0..30 {         let ms = rand::thread_rng().gen_range(0..=40);         sleep(Duration::from_millis(ms)).await;         print!(\"{}\", name);         stdout().flush().ok();     } }  #[tokio::main] async fn main() {     let a = spawn(do_work(\"a\".into()));     let b = spawn(do_work(\"b\".into()));     a.await.unwrap();     b.await.unwrap();     println!(); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet abababbabababbabbabaabababbbaabaabaabbabaabbabbabababaababaa<\/code><\/pre>\n<p>  \u0412\u044b\u0432\u043e\u0434 <code>strace<\/code> \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0435\u043d:<\/p>\n<pre><code class=\"bash\">$ cargo build --quiet &amp;&amp; strace -e write -f .\/target\/debug\/lox > \/dev\/null strace: Process 1413863 attached strace: Process 1413864 attached strace: Process 1413865 attached strace: Process 1413866 attached strace: Process 1413867 attached strace: Process 1413868 attached strace: Process 1413869 attached strace: Process 1413870 attached strace: Process 1413871 attached strace: Process 1413872 attached strace: Process 1413873 attached strace: Process 1413874 attached strace: Process 1413875 attached strace: Process 1413876 attached strace: Process 1413877 attached strace: Process 1413878 attached strace: Process 1413879 attached strace: Process 1413880 attached strace: Process 1413881 attached strace: Process 1413882 attached strace: Process 1413883 attached strace: Process 1413884 attached strace: Process 1413885 attached strace: Process 1413886 attached strace: Process 1413887 attached strace: Process 1413888 attached strace: Process 1413889 attached strace: Process 1413890 attached strace: Process 1413891 attached strace: Process 1413892 attached strace: Process 1413893 attached strace: Process 1413894 attached [pid 1413893] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413863] write(1, \"a\", 1)          = 1 [pid 1413863] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413863] write(1, \"a\", 1)          = 1 [pid 1413863] write(1, \"a\", 1)          = 1 [pid 1413893] write(1, \"b\", 1 &lt;unfinished ...> [pid 1413863] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8 &lt;unfinished ...> [pid 1413893] &lt;... write resumed>)      = 1 [pid 1413863] &lt;... write resumed>)      = 8 [pid 1413893] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(1, \"a\", 1)          = 1 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(1, \"a\", 1)          = 1 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413862] write(1, \"\\n\", 1)         = 1 [pid 1413862] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413867] +++ exited with 0 +++ [pid 1413863] +++ exited with 0 +++ [pid 1413864] +++ exited with 0 +++ [pid 1413868] +++ exited with 0 +++ [pid 1413865] +++ exited with 0 +++ [pid 1413866] +++ exited with 0 +++ [pid 1413869] +++ exited with 0 +++ [pid 1413870] +++ exited with 0 +++ [pid 1413873] +++ exited with 0 +++ [pid 1413871] +++ exited with 0 +++ [pid 1413872] +++ exited with 0 +++ [pid 1413874] +++ exited with 0 +++ [pid 1413875] +++ exited with 0 +++ [pid 1413876] +++ exited with 0 +++ [pid 1413878] +++ exited with 0 +++ [pid 1413877] +++ exited with 0 +++ [pid 1413879] +++ exited with 0 +++ [pid 1413880] +++ exited with 0 +++ [pid 1413881] +++ exited with 0 +++ [pid 1413882] +++ exited with 0 +++ [pid 1413883] +++ exited with 0 +++ [pid 1413884] +++ exited with 0 +++ [pid 1413885] +++ exited with 0 +++ [pid 1413886] +++ exited with 0 +++ [pid 1413887] +++ exited with 0 +++ [pid 1413888] +++ exited with 0 +++ [pid 1413891] +++ exited with 0 +++ [pid 1413890] +++ exited with 0 +++ [pid 1413889] +++ exited with 0 +++ [pid 1413893] +++ exited with 0 +++ [pid 1413892] +++ exited with 0 +++ [pid 1413894] +++ exited with 0 +++ +++ exited with 0 +++<\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043c\u044b \u0437\u0430\u043c\u0435\u0447\u0430\u0435\u043c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432! \u0422\u043e\u0447\u043d\u0435\u0435, \u0438\u0445 32. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0433\u0438\u043f\u0435\u0440\u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435.<\/p>\n<p>  \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0437\u0430\u043c\u0435\u0447\u0430\u0435\u043c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u2014 \u0437\u0430\u0434\u0430\u0447\u0438 a \u0438 b, \u043f\u043e\u0445\u043e\u0436\u0435, \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443:<\/p>\n<pre><code class=\"bash\">========= 93 [pid 1413893] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 ========= 63 [pid 1413863] write(1, \"a\", 1)          = 1 [pid 1413863] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413863] write(1, \"a\", 1)          = 1 [pid 1413863] write(1, \"a\", 1)          = 1 ========= 93 [pid 1413893] write(1, \"b\", 1 &lt;unfinished ...> ========= 63 [pid 1413863] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8 &lt;unfinished ...> ========= 93 [pid 1413893] &lt;... write resumed>)      = 1 ========= 63 [pid 1413863] &lt;... write resumed>)      = 8 ========= 93 [pid 1413893] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 ========= 94 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(1, \"a\", 1)          = 1 [pid 1413894] write(1, \"b\", 1)          = 1 [pid 1413894] write(1, \"a\", 1)          = 1 [pid 1413894] write(1, \"b\", 1)          = 1 ========= 62 [pid 1413862] write(1, \"\\n\", 1)         = 1 [pid 1413862] write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8) = 8<\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430 \u043d\u0430 Rust \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u0430 \u043a \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 \u043a\u043e\u0434\u0443 \u043d\u0430 Go.<\/p>\n<p>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u043d\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438\/\u0433\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u041e\u0421, \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e:<\/p>\n<pre><code class=\"rust\">\/\/ omitted: everything else  #[tokio::main(flavor = \"current_thread\")] async fn main() {     let a = spawn(do_work(\"a\".into()));     let b = spawn(do_work(\"b\".into()));     a.await.unwrap();     b.await.unwrap();     println!(); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo build --quiet &amp;&amp; strace -e write -f .\/target\/debug\/lox > \/dev\/null write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"a\", 1)                        = 1 write(1, \"b\", 1)                        = 1 write(1, \"a\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"a\", 1)                        = 1 write(1, \"b\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"b\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"a\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"a\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"b\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"b\", 1)                        = 1 write(4, \"\\1\\0\\0\\0\\0\\0\\0\\0\", 8)         = 8 write(1, \"\\n\", 1)                       = 1 +++ exited with 0 +++<\/code><\/pre>\n<p>  \u0412\u043e\u0442! \u0418 \u044d\u0442\u043e\u0442 \u0432\u044b\u0432\u043e\u0434 <em>\u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435<\/em> \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439: \u0442\u0430\u0439\u043c\u0435\u0440 tokio \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/tokio.rs\/blog\/2018-03-timers\" rel=\"nofollow noopener noreferrer\">hashed<br \/>  timing wheel<\/a>. \u042d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0437\u0434\u043e\u0440\u043e\u0432\u043e.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c \u0433\u043e\u043d\u043a\u0438<\/h2>\n<p>  \u0418 \u0432 Go, \u0438 \u0432 Rust \u0435\u0441\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u0430\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0442\u043a\u0438. \u0412 Rust \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (async runtime), \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c async runtime, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u043b\u0438 \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u0441\u0451 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u0435.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438, \u043c\u044b \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043d\u0430 \u043e\u043f\u0430\u0441\u043d\u0443\u044e \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e.<\/p>\n<p>  \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f\u0434\u0435\u0440 CPU \u043c\u043e\u0433\u0443\u0442 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u043f\u0430\u043c\u044f\u0442\u0438, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>  \u0412\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 Go:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\" )  func doWork(counter *int) {   for i := 0; i &lt; 100000; i++ {     *counter += 1   } }  func main() {   var wg sync.WaitGroup   counter := 0    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u0441\u0447\u0451\u0442\u0438\u043a\u0430 \u0441\u0442\u043e \u0442\u044b\u0441\u044f\u0447 \u0440\u0430\u0437, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c, \u0447\u0442\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e \u0434\u0432\u0443\u043c\u0441\u0442\u0430\u043c \u0442\u044b\u0441\u044f\u0447\u0430\u043c.<\/p>\n<p>  \u041d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e:<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/07 15:02:18 counter = 158740  $ go run .\/sample.go 2022\/02\/07 15:02:19 counter = 140789  $ go run .\/sample.go 2022\/02\/07 15:02:19 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:02:21 counter = 172553<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0434\u0438\u043d\u0438\u0446\u0443, \u0434\u0430\u043b\u0435\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>A \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 10<\/li>\n<li>B \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 10<\/li>\n<li>A \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: 11<\/li>\n<li>B \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: 11<\/li>\n<li>B \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 11 \u0432 \u0441\u0447\u0451\u0442\u0447\u0438\u043a<\/li>\n<li>A \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 11 \u0432 \u0441\u0447\u0451\u0442\u0447\u0438\u043a<\/li>\n<\/ul>\n<p>  \u0418 \u0442\u0430\u043a \u043c\u044b \u0442\u0435\u0440\u044f\u0435\u043c \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u044d\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e. \u0422\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u0432\u0441\u0435 \u0434\u0432\u0435\u0441\u0442\u0438 \u0442\u044b\u0441\u044f\u0447 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0438 \u044f \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u0436\u0435 \u0431\u044b\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443, \u043a\u043e\u0433\u0434\u0430 \u0431\u044b\u043b\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0432\u0442\u043e\u0440\u0430\u044f.<\/p>\n<p>  \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c: \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\"   \"sync\/atomic\" )  func doWork(counter *int64) {   for i := 0; i &lt; 100000; i++ {     atomic.AddInt64(counter, 1)   } }  func main() {   var wg sync.WaitGroup   var counter int64 = 0    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/07 15:09:10 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:09:11 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:09:11 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:09:11 counter = 200000 <\/code><\/pre>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>+<\/code> \u0438\u043b\u0438 <code>+=<\/code>, \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u043c\u0435\u044e\u0442 \u043e\u0441\u043e\u0431\u0443\u044e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443.<\/p>\n<p>  \u0418\u043b\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Mutex<\/code>, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0433\u043b\u0443\u043f\u043e\u0441\u0442\u044c\u044e, \u043d\u043e \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\" )  func doWork(counter *int64, mutex sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     mutex.Lock()     *counter += 1     mutex.Unlock()   } }  func main() {   var wg sync.WaitGroup   var counter int64 = 0   var mutex sync.Mutex    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter, mutex)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  \u0418 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/07 15:14:47 counter = 190245  $ go run .\/sample.go 2022\/02\/07 15:14:48 counter = 189107  $ go run .\/sample.go 2022\/02\/07 15:14:48 counter = 164618  $ go run .\/sample.go 2022\/02\/07 15:14:49 counter = 178458 <\/code><\/pre>\n<p>  \u2026 \u0425\u043e\u0442\u044f \u043d\u0435\u0442, \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  \u0418 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0435\u0442!<\/p>\n<p>  \u0425\u043c, \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u00abgo vet\u00bb.<\/p>\n<pre><code class=\"bash\">$ go vet .\/sample.go # command-line-arguments .\/sample.go:8:35: doWork passes lock by value: sync.Mutex .\/sample.go:25:21: call of doWork copies lock value: sync.Mutex<\/code><\/pre>\n<p>  \u041e, \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043e\u043f\u0438\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<p>  \u041a\u0430\u043a \u0433\u043b\u0443\u043f\u043e \u0441 \u043c\u043e\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b! \u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f.<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\" )  func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     mutex.Lock()     *counter += 1     mutex.Unlock()   } }  func main() {   var wg sync.WaitGroup   var counter int64 = 0   var mutex sync.Mutex    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter, &amp;mutex)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/07 15:16:59 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:17:00 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:17:00 counter = 200000  $ go run .\/sample.go 2022\/02\/07 15:17:01 counter = 200000<\/code><\/pre>\n<p>  \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  \u00abMutex\u00bb \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u00ab\u0432\u0437\u0430\u0438\u043c\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u00bb (mutual exclusion); \u0437\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e <em>\u043e\u0434\u043d\u0430<\/em> \u0437\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0435 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>A \u0438 B \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443<\/li>\n<li>B \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443<\/li>\n<li>B \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0447\u0451\u0442\u0447\u0438\u043a: 10<\/li>\n<li>B \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: 11<\/li>\n<li>B \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 11 \u0432 \u0441\u0447\u0451\u0442\u0447\u0438\u043a<\/li>\n<li>B \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443<\/li>\n<li>A \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443<\/li>\n<li>A \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443<\/li>\n<li>A \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0447\u0451\u0442\u0447\u0438\u043a: 11<\/li>\n<li>A \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: 12<\/li>\n<li>A \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 12 \u0432 \u0441\u0447\u0451\u0442\u0447\u0438\u043a<\/li>\n<\/ul>\n<p>  \u2026 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p>  \u0421 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u043e\u0432 \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>  \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0432 Go, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0438 \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u044c\u043d\u044b, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u044b\u043c\u0438 \u0438 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u044c\u044e\u0442\u0435\u043a\u0441 <em>\u0434\u043e \u0442\u043e\u0433\u043e<\/em>, \u043a\u0430\u043a \u043f\u0440\u0438\u043a\u0430\u0441\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0443.<\/p>\n<p>  \u041b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"go\">func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     \/\/ woops forgot to use the mutex     *counter += 1   } }<\/code><\/pre>\n<p>  \u0418 \u043c\u044b \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0438 <code>go build<\/code>, \u043d\u0438 <code>go vet<\/code> \u043d\u0435 \u0432\u0438\u0434\u044f\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043b\u043e\u0445\u043e\u0433\u043e \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435.<\/p>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0438 \u0441\u0447\u0451\u0442\u0447\u0438\u043a, \u0438 \u043c\u044c\u044e\u0442\u0435\u043a\u0441, \u043d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043a\u0440\u0430\u0441\u0438\u0432\u043e:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\" )  type ProtectedCounter struct {   value int64   mutex sync.Mutex }  func (pc *ProtectedCounter) inc() {   pc.mutex.Lock()   pc.value++   pc.mutex.Unlock() }  func (pc *ProtectedCounter) read() int64 {   pc.mutex.Lock()   value := pc.value   pc.mutex.Unlock()   return value }  func doWork(pc *ProtectedCounter) {   for i := 0; i &lt; 100000; i++ {     pc.inc()   } }  func main() {   var wg sync.WaitGroup   var pc ProtectedCounter    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;pc)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", pc.read()) }<\/code><\/pre>\n<p>  \u0418 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u043c \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a <code>ProtectedCounter.value<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e:<\/p>\n<pre><code class=\"go\">func doWork(pc *ProtectedCounter) {   for i := 0; i &lt; 100000; i++ {     pc.value += 1   } }<\/code><\/pre>\n<p>  \u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0443\u0447\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0449\u0438\u0449\u0451\u043d\u043d\u044b\u0439 \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0430\u043a\u0435\u0442.<\/p>\n<pre><code class=\"bash\">$ go mod init fasterthanli.me\/sample<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ in `sample\/protected\/protected.go`  package protected  import \"sync\"  \/\/ Uppercase => exported type Counter struct {   \/\/ lowercase => unexported   value int64   mutex sync.Mutex }  \/\/ Uppercase => exported func (pc *Counter) Inc() {   pc.mutex.Lock()   pc.value++   pc.mutex.Unlock() }  \/\/ Uppercase => exported func (pc *Counter) Read() int64 {   pc.mutex.Lock()   value := pc.value   pc.mutex.Unlock()   return value }<\/code><\/pre>\n<p>  \u0418 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code class=\"go\">\/\/ in `sample\/sample.go`  package main  import (   \"log\"   \"sync\"    \"fasterthanli.me\/sample\/protected\" )  func doWork(pc *protected.Counter) {   for i := 0; i &lt; 100000; i++ {     pc.Inc()   } }  func main() {   var wg sync.WaitGroup   var pc protected.Counter    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;pc)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", pc.Read()) }<\/code><\/pre>\n<p>  \u041d\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432\u044b\u043b\u0435\u0442\u0438\u0442 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"go\">func doWork(pc *protected.Counter) {   for i := 0; i &lt; 100000; i++ {     pc.value += 1   } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go build .\/sample.go # command-line-arguments .\/sample.go:12:5: pc.value undefined (cannot refer to unexported field or method value)<\/code><\/pre>\n<p>  \u041f\u043e\u0447\u0435\u043c\u0443 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442, \u0438\u043b\u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u043c \u0438\u0445 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432, \u043d\u0430\u0432\u0435\u0440\u043d\u043e, \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043d\u0438 \u043c\u043d\u0435, \u043d\u0438 \u0432\u0430\u043c.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a Rust.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0431\u0430\u0433, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043e\u0434\u043d\u0438\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u043c:<\/p>\n<pre><code class=\"rust\">use std::thread::spawn;  fn do_work(counter: &amp;mut u64) {     for _ in 0..100_000 {         *counter += 1     } }  fn main() {     let mut counter = 0;      let a = spawn(|| do_work(&amp;mut counter));     a.join().unwrap();      println!(\"counter = {counter}\") }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0373]: closure may outlive the current function, but it borrows `counter`, which is owned by the current function   --> src\/main.rs:12:19    | 12 |     let a = spawn(|| do_work(&amp;mut counter));    |                   ^^              ------- `counter` is borrowed here    |                   |    |                   may outlive borrowed value `counter`    | note: function requires argument type to outlive `'static`   --> src\/main.rs:12:13    | 12 |     let a = spawn(|| do_work(&amp;mut counter));    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `counter` (and any other referenced variables), use the `move` keyword    | 12 |     let a = spawn(move || do_work(&amp;mut counter));    |                   ++++  error[E0502]: cannot borrow `counter` as immutable because it is also borrowed as mutable   --> src\/main.rs:15:25    | 12 |     let a = spawn(|| do_work(&amp;mut counter));    |             -------------------------------    |             |     |               |    |             |     |               first borrow occurs due to use of `counter` in closure    |             |     mutable borrow occurs here    |             argument requires that `counter` is borrowed for `'static` ... 15 |     println!(\"counter = {counter}\")    |                         ^^^^^^^^^ immutable borrow occurs here  Some errors have detailed explanations: E0373, E0502. For more information about an error, try `rustc --explain E0373`. error: could not compile `lox` due to 2 previous errors<\/code><\/pre>\n<p>  \u0425\u043c, \u043d\u0435\u0442, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0443\u0436\u0435 \u043d\u0435\u0434\u043e\u0432\u043e\u043b\u0435\u043d. \u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c <em>\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e<\/em> \u043c\u0435\u043d\u044c\u0448\u0435.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>do_work<\/code> \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043b\u044c\u0448\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430. \u042d\u0442\u043e \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c.<\/p>\n<pre><code class=\"rust\">use std::thread::spawn;  fn do_work() {     for _ in 0..100_000 {         COUNTER += 1     } }  static mut COUNTER: u64 = 0;  fn main() {     let a = spawn(|| do_work());     a.join().unwrap();      println!(\"counter = {COUNTER}\") }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox) error[E0133]: use of mutable static is unsafe and requires unsafe function or block  --> src\/main.rs:5:9   | 5 |         COUNTER += 1   |         ^^^^^^^^^^^^ use of mutable static   |   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior  error[E0133]: use of mutable static is unsafe and requires unsafe function or block   --> src\/main.rs:15:25    | 15 |     println!(\"counter = {COUNTER}\")    |                         ^^^^^^^^^ use of mutable static    |    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior  For more information about this error, try `rustc --explain E0133`. error: could not compile `lox` due to 2 previous errors<\/code><\/pre>\n<p>  \u0425\u043c. \u042d\u0442\u043e \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e? <em>\u042d\u0442\u043e<\/em> \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e?<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u044d\u0442\u0443 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0443:<\/p>\n<blockquote><p>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: mutable static \u043c\u043e\u0433\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438: \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044f \u0430\u043b\u0438\u0430\u0441\u0438\u043d\u0433\u0430 \u0438\u043b\u0438 \u0433\u043e\u043d\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0443\u0442 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/p><\/blockquote>\n<p>  \u2026 \u0438 \u0437\u0430\u0439\u0434\u0451\u043c \u043d\u0430 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e.<\/p>\n<pre><code class=\"rust\">use std::thread::spawn;  fn do_work() {     for _ in 0..100_000 {         unsafe { COUNTER += 1 }     } }  static mut COUNTER: u64 = 0;  fn main() {     let a = spawn(|| do_work());     a.join().unwrap();      println!(\"counter = {}\", unsafe { COUNTER }) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet counter = 100000<\/code><\/pre>\n<p>  \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e!<\/p>\n<p>  \u0414\u0430, \u043d\u043e \u0443 \u043d\u0430\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u043e\u043a, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a <code>COUNTER<\/code>.<\/p>\n<p>  \u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e, \u0442\u0430\u043a \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0434\u0432\u0430:<\/p>\n<pre><code class=\"rust\">use std::thread::spawn;  fn do_work() {     for _ in 0..100_000 {         unsafe { COUNTER += 1 }     } }  static mut COUNTER: u64 = 0;  fn main() {     let a = spawn(|| do_work());     let b = spawn(|| do_work());     a.join().unwrap();     b.join().unwrap();      println!(\"counter = {}\", unsafe { COUNTER }) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet counter = 103946  $ cargo run --quiet counter = 104384  $ cargo run --quiet counter = 104845  $ cargo run --quiet counter = 104596<\/code><\/pre>\n<p>  \u0410\u0433\u0430, \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c! \u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043a\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0442 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u0438\u043b\u044c\u043d\u0435\u0435, \u0447\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 Go \u2014 \u043c\u044b \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 90 \u0442\u044b\u0441\u044f\u0447 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0431\u0430\u0433! \u041d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>unsafe<\/code>.<\/p>\n<p>  \u041c\u0435\u043d\u044f \u043d\u0430\u043f\u0440\u044f\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0441 \u043d\u0435\u0439 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>  \u041f\u043e\u043a\u0430 <a href=\"https:\/\/github.com\/rust-lang\/rfcs\/pull\/3151\" rel=\"nofollow noopener noreferrer\">\u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435<\/a>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/lib.rs\/crates\/crossbeam\" rel=\"nofollow noopener noreferrer\">crossbeam<\/a>:<\/p>\n<pre><code class=\"rust\">fn do_work(counter: &amp;mut u64) {     for _ in 0..100_000 {         *counter += 1     } }  fn main() {     let mut counter = 0;      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;mut counter));     })     .unwrap();      println!(\"counter = {}\", counter) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet counter = 100000<\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0434\u0435\u0441\u044c \u0432\u0442\u043e\u0440\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u043e\u0434\u0438\u043d \u0438\u0437 \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c Rust <em>\u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e<\/em> \u043e\u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0435\u043d:<\/p>\n<pre><code class=\"rust\">fn do_work(counter: &amp;mut u64) {     for _ in 0..100_000 {         *counter += 1     } }  fn main() {     let mut counter = 0;      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;mut counter));         s.spawn(|_| do_work(&amp;mut counter));     })     .unwrap();      println!(\"counter = {}\", counter) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet error[E0499]: cannot borrow `counter` as mutable more than once at a time   --> src\/main.rs:12:17    | 11 |         s.spawn(|_| do_work(&amp;mut counter));    |                 ---              ------- first borrow occurs due to use of `counter` in closure    |                 |    |                 first mutable borrow occurs here 12 |         s.spawn(|_| do_work(&amp;mut counter));    |           ----- ^^^              ------- second borrow occurs due to use of `counter` in closure    |           |     |    |           |     second mutable borrow occurs here    |           first borrow later used by call  For more information about this error, try `rustc --explain E0499`. error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u041e\u043d \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e <em>\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0435<\/em> \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0430! \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u0438 \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0431\u044b \u043d\u0435 \u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043e\u0442\u0432\u0435\u0440\u0433 \u0431\u044b \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434. \u041e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c <i>\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c<\/i> \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c \u0441\u0441\u044b\u043b\u043a\u0430\u043c \u043d\u0430 \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/doc.rust-lang.org\/stable\/std\/sync\/atomic\/struct.AtomicU64.html\" rel=\"nofollow noopener noreferrer\">AtomicU64<\/a>, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0432 Go (\u0445\u043e\u0442\u044f \u044d\u0442\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0438\u043f):<\/p>\n<pre><code class=\"rust\">use std::sync::atomic::{AtomicU64, Ordering};  fn do_work(counter: &amp;AtomicU64) {     for _ in 0..100_000 {         counter.fetch_add(1, Ordering::SeqCst);     } }  fn main() {     let counter: AtomicU64 = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;counter));         s.spawn(|_| do_work(&amp;counter));     })     .unwrap();      println!(\"counter = {}\", counter.load(Ordering::SeqCst)) }<\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>fetch_add<\/code> \u0438\u043b\u0438 \u0434\u043b\u044f <code>load<\/code>: \u0437\u0434\u0435\u0441\u044c \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e <a href=\"https:\/\/doc.rust-lang.org\/stable\/std\/sync\/atomic\/enum.Ordering.html#variant.SeqCst\" rel=\"nofollow noopener noreferrer\">SeqCst<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f \u0437\u043d\u0430\u044e, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u0439 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0435\u0439: \u0432\u0441\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0432\u0438\u0434\u044f\u0442 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000<\/code><\/pre>\n<p>  \u0418\u043b\u0438 \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/doc.rust-lang.org\/stable\/std\/sync\/struct.Mutex.html\" rel=\"nofollow noopener noreferrer\">Mutex<\/a>:<\/p>\n<pre><code class=\"rust\">use std::sync::Mutex;  fn do_work(counter: &amp;Mutex&lt;u64>) {     for _ in 0..100_000 {         let mut counter = counter.lock().unwrap();         *counter += 1     } }  fn main() {     let counter: Mutex&lt;u64> = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;counter));         s.spawn(|_| do_work(&amp;counter));     })     .unwrap();      println!(\"counter = {}\", counter.lock().unwrap()) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000  $ cargo run --quiet counter = 200000<\/code><\/pre>\n<p>  \u0418 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043d\u0430 Go \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0435 <code>(Mutex, u64)<\/code>, \u0430 <code>Mutex&lt;u64><\/code>. \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0438\u0441\u043a \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0431\u0435\u0437 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439.<\/p>\n<p>  \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c <em>\u0441\u0431\u043e\u0439<\/em>. \u0418 \u044d\u0442\u043e \u0444\u0438\u0447\u0430: \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u043f\u0430\u043d\u0438\u043a\u0443\u0435\u0442, \u043f\u043e\u043a\u0430 \u0434\u0435\u0440\u0436\u0438\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430, \u0442\u0438\u043f <code>std::sync::Mutex<\/code> \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u00ab\u043e\u0442\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u00bb. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043d\u0441\u0435\u0440\u0432\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0437\u0440\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043a \u043c\u043e\u0433 \u0438\u043c\u0435\u0442\u044c \u043f\u0430\u043d\u0438\u043a\u0443 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043c\u043d\u043e\u0433\u043e\u044d\u0442\u0430\u043f\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0438 \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u043c.<\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0438\u0437 <code>PoisonError<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0430\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b, \u0438 \u0435\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u043f\u0430\u043d\u0438\u043a\u043e\u0432\u0430\u0442\u044c). \u041e\u0434\u043d\u0430\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0438\u0434\u0435\u043d\u043d\u044b\u0445 \u043c\u043d\u043e\u0439 \u043a\u043e\u0434\u043e\u0432\u044b\u0445 \u0431\u0430\u0437 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0442\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u041d\u043e \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0438\u0434\u0435\u043d\u043d\u044b\u0445 \u043c\u043d\u043e\u0439 \u043a\u043e\u0434\u043e\u0432\u044b\u0445 \u0431\u0430\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <code>Mutex<\/code> \u0438\u0437 <a href=\"https:\/\/lib.rs\/crates\/parking_lot\" rel=\"nofollow noopener noreferrer\">parking_lot<\/a>, \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432, \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0434\u0440\u0443\u0433\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f: \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0430\u043d\u0438\u043a\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 \u043f\u0440\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u043c\u044c\u044e\u0442\u0435\u043a\u0441 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<pre><code class=\"rust\">use parking_lot::Mutex;  fn do_work(counter: &amp;Mutex&lt;u64>) {     for _ in 0..100_000 {         \/\/ ? no more .unwrap()!         let mut counter = counter.lock();         *counter += 1     } }  fn main() {     let counter: Mutex&lt;u64> = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;counter));         s.spawn(|_| do_work(&amp;counter));     })     .unwrap();      \/\/ ? no more .unwrap()!     println!(\"counter = {}\", counter.lock()) }<\/code><\/pre>\n<p>  \u0422\u0440\u0435\u0442\u044c\u044f \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u2026 \u043c\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c \u043c\u044c\u044e\u0442\u0435\u043a\u0441? \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u044f\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0442\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u0412 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 Go \u043c\u044b \u044f\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 <code>Lock()<\/code> \u0438 <code>Unlock()<\/code> \u2014 \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>Unlock()<\/code>, \u0432\u0441\u0451 \u0438\u0434\u0451\u0442 \u043d\u0430\u043f\u0435\u0440\u0435\u043a\u043e\u0441\u044f\u043a:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"sync\" )  func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     mutex.Lock()     *counter += 1     \/\/ ? woops, no unlock!   } }  func main() {   var wg sync.WaitGroup   var counter int64 = 0   var mutex sync.Mutex    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter, &amp;mutex)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  \u0418 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u2026 \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 (deadlock). \u0411\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f. \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u0430\u0436\u0434\u0430\u044f \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0436\u0434\u0451\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u0430 \u0443\u0436\u0435 \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f\u0441\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u0436\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0430.<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go fatal error: all goroutines are asleep - deadlock!  goroutine 1 [semacquire]: sync.runtime_Semacquire(0x0)         \/usr\/local\/go\/src\/runtime\/sema.go:56 +0x25 sync.(*WaitGroup).Wait(0xc000114000)         \/usr\/local\/go\/src\/sync\/waitgroup.go:130 +0x71 main.main()         \/home\/amos\/bearcove\/lox\/sample.go:29 +0xfb  goroutine 18 [semacquire]: sync.runtime_SemacquireMutex(0x0, 0x0, 0x0)         \/usr\/local\/go\/src\/runtime\/sema.go:71 +0x25 sync.(*Mutex).lockSlow(0xc00013a018)         \/usr\/local\/go\/src\/sync\/mutex.go:138 +0x165 sync.(*Mutex).Lock(...)         \/usr\/local\/go\/src\/sync\/mutex.go:81 main.doWork(0xc00013a010, 0xc00013a018)         \/home\/amos\/bearcove\/lox\/sample.go:10 +0x58 main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:25 +0x5c created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:23 +0x5a  goroutine 19 [semacquire]: sync.runtime_SemacquireMutex(0x0, 0x0, 0x0)         \/usr\/local\/go\/src\/runtime\/sema.go:71 +0x25 sync.(*Mutex).lockSlow(0xc00013a018)         \/usr\/local\/go\/src\/sync\/mutex.go:138 +0x165 sync.(*Mutex).Lock(...)         \/usr\/local\/go\/src\/sync\/mutex.go:81 main.doWork(0xc00013a010, 0xc00013a018)         \/home\/amos\/bearcove\/lox\/sample.go:10 +0x58 main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:25 +0x5c created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:23 +0x5a exit status 2<\/code><\/pre>\n<p>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0441\u0440\u0435\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f Go \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0451\u0442 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0438 \u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0435.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u0430\u043c \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442:<\/p>\n<pre><code class=\"go\">\/\/ omitted: everything except main  func main() {   go func() {     for {       time.Sleep(time.Second)     }   }()    var wg sync.WaitGroup   var counter int64 = 0   var mutex sync.Mutex    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter, &amp;mutex)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go  (no output, ever)<\/code><\/pre>\n<p>  \u0420\u0430\u0434\u0438 \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u043a Go \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u00abnet\/http\/pprof\u00bb, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c HTTP-\u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445.<\/p>\n<p>  \u0412 <a href=\"https:\/\/pkg.go.dev\/net\/http\/pprof\" rel=\"nofollow noopener noreferrer\"><code>\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u043e net\/http\/pprof<\/code><\/a> \u0435\u0441\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435. \u0412 \u0441\u0432\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"go\">import _ \"net\/http\/pprof\" \/\/ omitted: other imports  func main() {   log.Println(http.ListenAndServe(\"localhost:6060\", nil))      \/\/ omitted: rest of main }<\/code><\/pre>\n<p>  \u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go<\/code><\/pre>\n<p>  \u0418 \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>localhost:6060<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"bash\">$ curl 'http:\/\/localhost:6060\/debug\/pprof\/goroutine?debug=1' goroutine profile: total 3 1 @ 0x439236 0x431bf3 0x4631e9 0x4a91d2 0x4aa86c 0x4aa859 0x5456f5 0x5569c8 0x555d1d 0x5f7334 0x5f6f5d 0x6464a5 0x646479 0x438e67 0x468641 #       0x4631e8        internal\/poll.runtime_pollWait+0x88             \/usr\/local\/go\/src\/runtime\/netpoll.go:234 #       0x4a91d1        internal\/poll.(*pollDesc).wait+0x31             \/usr\/local\/go\/src\/internal\/poll\/fd_poll_runtime.go:84 #       0x4aa86b        internal\/poll.(*pollDesc).waitRead+0x22b        \/usr\/local\/go\/src\/internal\/poll\/fd_poll_runtime.go:89 #       0x4aa858        internal\/poll.(*FD).Accept+0x218                \/usr\/local\/go\/src\/internal\/poll\/fd_unix.go:402 #       0x5456f4        net.(*netFD).accept+0x34                        \/usr\/local\/go\/src\/net\/fd_unix.go:173 #       0x5569c7        net.(*TCPListener).accept+0x27                  \/usr\/local\/go\/src\/net\/tcpsock_posix.go:140 #       0x555d1c        net.(*TCPListener).Accept+0x3c                  \/usr\/local\/go\/src\/net\/tcpsock.go:262 #       0x5f7333        net\/http.(*Server).Serve+0x393                  \/usr\/local\/go\/src\/net\/http\/server.go:3002 #       0x5f6f5c        net\/http.(*Server).ListenAndServe+0x7c          \/usr\/local\/go\/src\/net\/http\/server.go:2931 #       0x6464a4        net\/http.ListenAndServe+0x44                    \/usr\/local\/go\/src\/net\/http\/server.go:3185 #       0x646478        main.main+0x18                                  \/home\/amos\/bearcove\/lox\/sample.go:20 #       0x438e66        runtime.main+0x226                              \/usr\/local\/go\/src\/runtime\/proc.go:255  1 @ 0x462d85 0x638af5 0x63890d 0x635a8b 0x64469a 0x64524e 0x5f418f 0x5f5a89 0x5f6dbb 0x5f34e8 0x468641 #       0x462d84        runtime\/pprof.runtime_goroutineProfileWithLabels+0x24   \/usr\/local\/go\/src\/runtime\/mprof.go:746 #       0x638af4        runtime\/pprof.writeRuntimeProfile+0xb4                  \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:724 #       0x63890c        runtime\/pprof.writeGoroutine+0x4c                       \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:684 #       0x635a8a        runtime\/pprof.(*Profile).WriteTo+0x14a                  \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:331 #       0x644699        net\/http\/pprof.handler.ServeHTTP+0x499                  \/usr\/local\/go\/src\/net\/http\/pprof\/pprof.go:253 #       0x64524d        net\/http\/pprof.Index+0x12d                              \/usr\/local\/go\/src\/net\/http\/pprof\/pprof.go:371 #       0x5f418e        net\/http.HandlerFunc.ServeHTTP+0x2e                     \/usr\/local\/go\/src\/net\/http\/server.go:2047 #       0x5f5a88        net\/http.(*ServeMux).ServeHTTP+0x148                    \/usr\/local\/go\/src\/net\/http\/server.go:2425 #       0x5f6dba        net\/http.serverHandler.ServeHTTP+0x43a                  \/usr\/local\/go\/src\/net\/http\/server.go:2879 #       0x5f34e7        net\/http.(*conn).serve+0xb07                            \/usr\/local\/go\/src\/net\/http\/server.go:1930  1 @ 0x468641<\/code><\/pre>\n<p>  \u041f\u043e\u0441\u0442\u043e\u0439\u0442\u0435, \u043d\u043e \u044d\u0442\u043e \u043d\u0435\u0432\u0435\u0440\u043d\u043e. \u042f \u0432\u0438\u0436\u0443 \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u044b HTTP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430\u2026<\/p>\n<p>  \u041e! \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b <em>\u043f\u043e\u0440\u043e\u0434\u0438\u0442\u044c<\/em> \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0435\u0433\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0435, \u043a\u0430\u043a\u0430\u044f \u0433\u043b\u0443\u043f\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442 \u0441\u0442\u043e\u043b\u044c \u0433\u043b\u0443\u043f\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<pre><code class=\"go\">\/\/ omitted: everything else  func main() {   go log.Println(http.ListenAndServe(\"localhost:6060\", nil))    \/\/ etc. }<\/code><\/pre>\n<p>  \u0425\u043c, \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u044b HTTP.<\/p>\n<p>  \u0411\u043b\u0438\u043d, \u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u044e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u0442\u0430\u043a\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c, \u043d\u0430\u0432\u0435\u0440\u043d\u043e, \u0441\u043e \u043c\u043d\u043e\u0439 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f\u2026 \u043e! \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u0432 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0434 \u0436\u0434\u0451\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 <code>http.ListenAndServe<\/code>, \u0447\u0442\u043e\u0431\u044b <em>\u0437\u0430\u0442\u0435\u043c<\/em> \u043e\u043d \u043c\u043e\u0433 \u043f\u043e\u0440\u043e\u0434\u0438\u0442\u044c <code>log.Println<\/code> \u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0435.<\/p>\n<p>  \u041a\u0430\u043a\u0430\u044f \u0433\u043b\u0443\u043f\u043e\u0441\u0442\u044c \u0441 \u043c\u043e\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b.<\/p>\n<pre><code class=\"go\">\/\/ omitted: everything else  func main() {   go func() {     log.Println(http.ListenAndServe(\"localhost:6060\", nil))   }()    \/\/ etc. }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ curl 'http:\/\/localhost:6060\/debug\/pprof\/goroutine?debug=1' goroutine profile: total 7 2 @ 0x439236 0x449eac 0x449e86 0x464845 0x479f05 0x646418 0x64642d 0x64663c 0x468641 #       0x464844        sync.runtime_SemacquireMutex+0x24       \/usr\/local\/go\/src\/runtime\/sema.go:71 #       0x479f04        sync.(*Mutex).lockSlow+0x164            \/usr\/local\/go\/src\/sync\/mutex.go:138 #       0x646417        sync.(*Mutex).Lock+0x57                 \/usr\/local\/go\/src\/sync\/mutex.go:81 #       0x64642c        main.doWork+0x6c                        \/home\/amos\/bearcove\/lox\/sample.go:13 #       0x64663b        main.main.func3+0x5b                    \/home\/amos\/bearcove\/lox\/sample.go:38  1 @ 0x439236 0x431bf3 0x4631e9 0x4a91d2 0x4aa86c 0x4aa859 0x5456f5 0x5569c8 0x555d1d 0x5f7334 0x5f6f5d 0x646725 0x6466f5 0x468641 #       0x4631e8        internal\/poll.runtime_pollWait+0x88             \/usr\/local\/go\/src\/runtime\/netpoll.go:234 #       0x4a91d1        internal\/poll.(*pollDesc).wait+0x31             \/usr\/local\/go\/src\/internal\/poll\/fd_poll_runtime.go:84 #       0x4aa86b        internal\/poll.(*pollDesc).waitRead+0x22b        \/usr\/local\/go\/src\/internal\/poll\/fd_poll_runtime.go:89 #       0x4aa858        internal\/poll.(*FD).Accept+0x218                \/usr\/local\/go\/src\/internal\/poll\/fd_unix.go:402 #       0x5456f4        net.(*netFD).accept+0x34                        \/usr\/local\/go\/src\/net\/fd_unix.go:173 #       0x5569c7        net.(*TCPListener).accept+0x27                  \/usr\/local\/go\/src\/net\/tcpsock_posix.go:140 #       0x555d1c        net.(*TCPListener).Accept+0x3c                  \/usr\/local\/go\/src\/net\/tcpsock.go:262 #       0x5f7333        net\/http.(*Server).Serve+0x393                  \/usr\/local\/go\/src\/net\/http\/server.go:3002 #       0x5f6f5c        net\/http.(*Server).ListenAndServe+0x7c          \/usr\/local\/go\/src\/net\/http\/server.go:2931 #       0x646724        net\/http.ListenAndServe+0x44                    \/usr\/local\/go\/src\/net\/http\/server.go:3185 #       0x6466f4        main.main.func1+0x14                            \/home\/amos\/bearcove\/lox\/sample.go:21  1 @ 0x439236 0x449eac 0x449e86 0x464725 0x47b751 0x64657b 0x438e67 0x468641 #       0x464724        sync.runtime_Semacquire+0x24    \/usr\/local\/go\/src\/runtime\/sema.go:56 #       0x47b750        sync.(*WaitGroup).Wait+0x70     \/usr\/local\/go\/src\/sync\/waitgroup.go:130 #       0x64657a        main.main+0x11a                 \/home\/amos\/bearcove\/lox\/sample.go:42 #       0x438e66        runtime.main+0x226              \/usr\/local\/go\/src\/runtime\/proc.go:255  1 @ 0x439236 0x4654ce 0x64679e 0x468641 #       0x4654cd        time.Sleep+0x12d        \/usr\/local\/go\/src\/runtime\/time.go:193 #       0x64679d        main.main.func2+0x1d    \/home\/amos\/bearcove\/lox\/sample.go:26  1 @ 0x462d85 0x638af5 0x63890d 0x635a8b 0x64469a 0x64524e 0x5f418f 0x5f5a89 0x5f6dbb 0x5f34e8 0x468641 #       0x462d84        runtime\/pprof.runtime_goroutineProfileWithLabels+0x24   \/usr\/local\/go\/src\/runtime\/mprof.go:746 #       0x638af4        runtime\/pprof.writeRuntimeProfile+0xb4                  \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:724 #       0x63890c        runtime\/pprof.writeGoroutine+0x4c                       \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:684 #       0x635a8a        runtime\/pprof.(*Profile).WriteTo+0x14a                  \/usr\/local\/go\/src\/runtime\/pprof\/pprof.go:331 #       0x644699        net\/http\/pprof.handler.ServeHTTP+0x499                  \/usr\/local\/go\/src\/net\/http\/pprof\/pprof.go:253 #       0x64524d        net\/http\/pprof.Index+0x12d                              \/usr\/local\/go\/src\/net\/http\/pprof\/pprof.go:371 #       0x5f418e        net\/http.HandlerFunc.ServeHTTP+0x2e                     \/usr\/local\/go\/src\/net\/http\/server.go:2047 #       0x5f5a88        net\/http.(*ServeMux).ServeHTTP+0x148                    \/usr\/local\/go\/src\/net\/http\/server.go:2425 #       0x5f6dba        net\/http.serverHandler.ServeHTTP+0x43a                  \/usr\/local\/go\/src\/net\/http\/server.go:2879 #       0x5f34e7        net\/http.(*conn).serve+0xb07                            \/usr\/local\/go\/src\/net\/http\/server.go:1930  1 @ 0x496ae5 0x494e2d 0x4a9da5 0x4a9d8d 0x4a9b45 0x544529 0x54ee45 0x5ed6bf 0x468641 #       0x496ae4        syscall.Syscall+0x4                             \/usr\/local\/go\/src\/syscall\/asm_linux_amd64.s:20 #       0x494e2c        syscall.read+0x4c                               \/usr\/local\/go\/src\/syscall\/zsyscall_linux_amd64.go:687 #       0x4a9da4        syscall.Read+0x284                              \/usr\/local\/go\/src\/syscall\/syscall_unix.go:189 #       0x4a9d8c        internal\/poll.ignoringEINTRIO+0x26c             \/usr\/local\/go\/src\/internal\/poll\/fd_unix.go:582 #       0x4a9b44        internal\/poll.(*FD).Read+0x24                   \/usr\/local\/go\/src\/internal\/poll\/fd_unix.go:163 #       0x544528        net.(*netFD).Read+0x28                          \/usr\/local\/go\/src\/net\/fd_posix.go:56 #       0x54ee44        net.(*conn).Read+0x44                           \/usr\/local\/go\/src\/net\/net.go:183 #       0x5ed6be        net\/http.(*connReader).backgroundRead+0x3e      \/usr\/local\/go\/src\/net\/http\/server.go:672<\/code><\/pre>\n<p>  \u0410\u0433\u0430, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u044b. \u0422\u0430\u043a \u0447\u0442\u043e \u0434\u0430, pprof \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0434\u043e\u0431\u0435\u043d! \u0423 \u043d\u0435\u0433\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u0447\u0435\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0437\u0434\u0435\u0441\u044c, \u0432\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>  \u0414\u043b\u044f Rust \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/lib.rs\/crates\/tokio-console\" rel=\"nofollow noopener noreferrer\">tokio-console<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 <em>\u043e\u0447\u0435\u043d\u044c<\/em> \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u043d\u0430 Rust!<\/p>\n<p>  \u0423 \u043d\u0430\u0441 \u0438\u043c\u0435\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"rust\">use parking_lot::Mutex;  fn do_work(counter: &amp;Mutex&lt;u64>) {     for _ in 0..100_000 {         let mut counter = counter.lock();         *counter += 1     } }  fn main() {     let counter: Mutex&lt;u64> = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;counter));         s.spawn(|_| do_work(&amp;counter));     })     .unwrap();      println!(\"counter = {}\", counter.lock()) }<\/code><\/pre>\n<p>  \u0418 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u044f\u0432\u043d\u043e\u0439 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430: \u0442\u0430\u043a \u043a\u0430\u043a <code>counter<\/code> \u0432 <code>let mut counter<\/code> \u0432 <code>fn do_work()<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>MutexGuard&lt;u64><\/code>, \u0430 \u044d\u0442\u043e\u0442 \u0442\u0438\u043f \u0438\u043c\u0435\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e <code>Drop<\/code>: \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>Mutex<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0449\u0438\u0442\u043d\u0430\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u0412 Go \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0442\u0442\u0435\u0440\u043d <code>defer mutex.Unlock()<\/code> \u0447\u0442\u043e\u0431\u044b <i>\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435<\/i>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e.<\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   _ \"net\/http\/pprof\"   \"sync\" )  func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     mutex.Lock()     defer mutex.Unlock()     *counter += 1   } }  func main() {   var wg sync.WaitGroup   var counter int64 = 0   var mutex sync.Mutex    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(&amp;counter, &amp;mutex)     }()   }    wg.Wait()   log.Printf(\"counter = %v\", counter) }<\/code><\/pre>\n<p>  \u041e\u043d \u0437\u0430\u0432\u0438\u0441\u0430\u0435\u0442 \u043d\u0430\u0432\u0435\u0447\u043d\u043e.<\/p>\n<p>  \u041c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u0436\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u00ab\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\u00bb, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0432\u0435\u0434\u044c \u0443 \u043d\u0430\u0441 \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442:<\/p>\n<pre><code class=\"go\">import _ \"net\/http\/pprof\"<\/code><\/pre>\n<p>  \u0417\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u044d\u0442\u043e? \u0423\u0436 \u0442\u043e\u0447\u043d\u043e \u043d\u0435\u0442.<\/p>\n<p>  \u0418 \u044d\u0442\u043e\u0442 \u0438\u043c\u043f\u043e\u0440\u0442 \u0438\u043c\u0435\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>init<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a \u0442\u0435\u0440\u043f\u0438\u0442 \u043a\u0440\u0430\u0445 (\u0434\u0430\u0436\u0435 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0435\u0449\u0451 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 HTTP-\u0441\u0435\u0440\u0432\u0435\u0440!)<\/p>\n<p>  \u041d\u043e \u0441\u0430\u043c\u0430 \u0441\u0443\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c: <code>defer<\/code> \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>\u0434\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 ambient function<\/em>. \u0410 \u043d\u0435 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0432\u0438\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442:<\/p>\n<pre><code class=\"go\">func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     mutex.Lock()     defer mutex.Unlock()     *counter += 1   } }<\/code><\/pre>\n<p>  \u0421\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043e\u0447\u0435\u043d.<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d:<\/p>\n<pre><code class=\"go\">func doWork(counter *int64, mutex *sync.Mutex) {   for i := 0; i &lt; 100000; i++ {     func() {       mutex.Lock()       defer mutex.Unlock()       *counter += 1     }()   } }<\/code><\/pre>\n<p>  \u0418 <em>\u043e\u043d<\/em> \u0443\u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.<\/p>\n<p>  \u0412\u0438\u0434\u0438\u0442\u0435 \u043b\u0438 \u0432\u044b \u0437\u0434\u0435\u0441\u044c \u0437\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c? \u041a\u043b\u044f\u043d\u0443\u0441\u044c, \u044f \u0434\u0430\u0436\u0435 \u043d\u0435 <i>\u043f\u044b\u0442\u0430\u044e\u0441\u044c<\/i> \u0438\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0449\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 Go: \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e. \u041f\u043e\u043a\u0430 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 <i>\u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439<\/i> \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p>  \u0418 \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e. <a href=\"https:\/\/fasterthanli.me\/articles\/i-want-off-mr-golangs-wild-ride\" rel=\"nofollow noopener noreferrer\">\u0413\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e<\/a>.<\/p>\n<p>  \u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u2014 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"go\">fn do_work(counter: &amp;Mutex&lt;u64>) {     for _ in 0..100_000 {         {             let mut counter = counter.lock();             *counter += 1         }         {             let mut counter = counter.lock();             *counter += 1         }     } }<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0434\u0432\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043f\u0435\u0440\u0432\u0430\u044f \u0437\u0430\u0449\u0438\u0442\u043d\u0430\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0443 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0448\u0430\u043d\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/p>\n<h2>\u041d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0443\u044e \u043a\u0430\u0440\u0442\u0443 \u0434\u043b\u044f \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043c\u0438\u0440\u0430<\/h2>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"go\">package main  import (   \"log\"   \"math\/rand\"   \"sync\" )  func doWork(m map[uint64]uint64) {   for i := 0; i &lt; 100; i++ {     key := uint64(rand.Intn(10))     m[key] += 1   } }  func main() {   var wg sync.WaitGroup   var m map[uint64]uint64    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(m)     }()   }    wg.Wait()   log.Printf(\"map = %#v\", m) }<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0434\u0443\u043c\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442? \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0435 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 map. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e!<\/p>\n<p>  \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f!<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go panic: assignment to entry in nil map  goroutine 7 [running]: main.doWork(0x0)         \/home\/amos\/bearcove\/lox\/sample.go:12 +0x48 main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:24 +0x58 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:22 +0x45 exit status 2<\/code><\/pre>\n<p>  \u0425\u043e\u0442\u044f \u043d\u0435\u0442, \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435, \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>  \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f map Go (nil)!<\/p>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>len()<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u0438 \u043c\u043e\u0436\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e, \u043d\u043e \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"rust\">package main  import \"log\"  func main() {   var m map[uint64]uint64   log.Printf(\"len(m) = %v\", len(m))   log.Printf(\"m[234] = %v\", m[234])   m[234] = 432 }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/scratch.go 2022\/02\/07 22:47:56 len(m) = 0 2022\/02\/07 22:47:56 m[234] = 0 panic: assignment to entry in nil map  goroutine 1 [running]: main.main()         \/home\/amos\/bearcove\/lox\/scratch.go:9 +0xb8 exit status 2<\/code><\/pre>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u043c \u044d\u0442\u043e\u0442 \u0431\u0430\u0433 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e:<\/p>\n<pre><code class=\"go\">\/\/ omitted: everything except main  func main() {   var wg sync.WaitGroup   m := make(map[uint64]uint64)    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(m)     }()   }    wg.Wait()   log.Printf(\"map = %#v\", m) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go 2022\/02\/07 22:49:17 map = map[uint64]uint64{0x0:0x19, 0x1:0x16, 0x2:0x10, 0x3:0x17, 0x4:0xe, 0x5:0x13, 0x6:0x16, 0x7:0x18, 0x8:0x15, 0x9:0xe}<\/code><\/pre>\n<p>  \u0425\u0430! \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>  \u041d\u043e \u043f\u043e\u0441\u0442\u043e\u0439\u0442\u0435-\u043a\u0430, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435?<\/p>\n<pre><code class=\"bash\">$ go get github.com\/davecgh\/go-spew\/spew<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ omitted: everything besides main  func main() {   var wg sync.WaitGroup   m := make(map[uint64]uint64)    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(m)     }()   }    wg.Wait()   \/\/ ? instead of using the \"%#v\" specifier   spew.Dump(m) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go (map[uint64]uint64) (len=10) {  (uint64) 8: (uint64) 21,  (uint64) 5: (uint64) 19,  (uint64) 6: (uint64) 22,  (uint64) 4: (uint64) 14,  (uint64) 2: (uint64) 16,  (uint64) 7: (uint64) 24,  (uint64) 9: (uint64) 14,  (uint64) 3: (uint64) 23,  (uint64) 1: (uint64) 22,  (uint64) 0: (uint64) 25 }<\/code><\/pre>\n<p>  \u0412\u043e\u0442, \u0442\u0430\u043a-\u0442\u043e \u043b\u0443\u0447\u0448\u0435!<\/p>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0431\u0430\u0433\u043e\u0432 \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c. \u041c\u044b \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c 200 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e 10 \u0443\u0447\u0430\u0441\u0442\u043a\u0430\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0432\u043d\u043e 20.<\/p>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0441\u0443\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>  \u041d\u0430\u0432\u0435\u0440\u043d\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Go!<\/p>\n<pre><code class=\"go\">func main() {   \/\/ omitted: start of main    sum := 0   for _, v := range m {     sum += v   }   spew.Dump(sum) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$  go run .\/sample.go # command-line-arguments .\/sample.go:34:7: invalid operation: sum += v (mismatched types int and uint64)<\/code><\/pre>\n<p>  \u0410-\u0445\u0430-\u0445\u0430. \u0414\u0430 \u043a\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<pre><code class=\"go\">func main() {   \/\/ omitted: start of main    sum := uint64(0) \/\/ you can't make me use var!   for _, v := range m {     sum += v   }   spew.Dump(sum) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go (map[uint64]uint64) (len=10) {  (uint64) 5: (uint64) 19,  (uint64) 0: (uint64) 25,  (uint64) 2: (uint64) 16,  (uint64) 7: (uint64) 24,  (uint64) 8: (uint64) 21,  (uint64) 6: (uint64) 22,  (uint64) 4: (uint64) 14,  (uint64) 3: (uint64) 23,  (uint64) 1: (uint64) 22,  (uint64) 9: (uint64) 14 } (uint64) 200  $ go run .\/sample.go (map[uint64]uint64) (len=10) {  (uint64) 7: (uint64) 24,  (uint64) 9: (uint64) 14,  (uint64) 8: (uint64) 21,  (uint64) 4: (uint64) 14,  (uint64) 2: (uint64) 16,  (uint64) 1: (uint64) 22,  (uint64) 5: (uint64) 19,  (uint64) 0: (uint64) 25,  (uint64) 6: (uint64) 22,  (uint64) 3: (uint64) 23 } (uint64) 200  $ go run .\/sample.go (map[uint64]uint64) (len=10) {  (uint64) 9: (uint64) 14,  (uint64) 0: (uint64) 25,  (uint64) 3: (uint64) 23,  (uint64) 1: (uint64) 22,  (uint64) 7: (uint64) 24,  (uint64) 8: (uint64) 21,  (uint64) 5: (uint64) 19,  (uint64) 6: (uint64) 22,  (uint64) 4: (uint64) 14,  (uint64) 2: (uint64) 16 } (uint64) 200<\/code><\/pre>\n<p>  \u0414\u0430, \u0442\u0443\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e! \u0418 \u0441\u0443\u043c\u043c\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0440\u0430\u0432\u043d\u0430 200!<\/p>\n<p>  \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e, \u0432\u0435\u0434\u044c \u043d\u0430\u043c \u0438 \u043d\u0443\u0436\u043d\u044b \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430.<\/p>\n<p>  \u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0435\u043d, \u043d\u043e \u044d\u0442\u043e \u0444\u0438\u0447\u0430:<\/p>\n<pre><code class=\"go\">package main  import \"fmt\"  func main() {   var m = make(map[string]struct{})   for _, s := range []string{\"a\", \"b\", \"c\", \"A\"} {     m[s] = struct{}{}   }    for i := 0; i &lt; 5; i++ {     for k := range m {       fmt.Printf(\"%v\", k)     }     fmt.Println()   } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/scratch.go bcAa cAab bcAa abcA Acab<\/code><\/pre>\n<p>  \u041b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u0430\u044f \u0438\u0434\u0435\u044f. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Map \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u044f\u0432\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u044e\u0442, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043b\u0438 \u043e\u043d\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u0441\u0442\u0430\u0432\u043e\u043a. <code>HashMap<\/code> \u0432 Rust \u0442\u043e\u0436\u0435 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u0441\u0442\u0430\u0432\u043e\u043a.<\/p>\n<pre><code class=\"go\">use std::collections::HashMap;  fn main() {     let mut map = HashMap::new();     map.insert(\"a\", 1);     map.insert(\"b\", 2);     map.insert(\"c\", 3);      for _ in 0..5 {         for k in map.keys() {             print!(\"{}\", k);         }         println!();     } }<\/code><\/pre>\n<p>  \u041d\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0440\u0430\u043d\u0434\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet  bca bca bca bca bca  $ cargo run --quiet abc abc abc abc abc  $ cargo run --quiet acb acb acb acb acb<\/code><\/pre>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u043b\u0438 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u0440\u0430\u043d\u0434\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u2014 \u0441\u043f\u043e\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u043d\u043e \u0443\u0436 \u0438\u043c\u0435\u0435\u043c, \u0447\u0442\u043e \u0438\u043c\u0435\u0435\u043c.<\/p>\n<p>  \u0412\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0430 Go: \u0438\u0442\u0430\u043a, \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e. \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443?<\/p>\n<p>  \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0446\u0438\u043a\u043b \u0432 <code>doWork<\/code>, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u043f\u044f\u0442\u044c\u0434\u0435\u0441\u044f\u0442 \u0442\u044b\u0441\u044f\u0447 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<pre><code class=\"go\">func doWork(m map[uint64]uint64) {   \/\/               ?   for i := 0; i &lt; 50000; i++ {     key := uint64(rand.Intn(10))     m[key] += 1   } }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go fatal error: concurrent map writes  goroutine 7 [running]: runtime.throw({0x4cb240, 0xc000086f60})         \/usr\/local\/go\/src\/runtime\/panic.go:1198 +0x71 fp=0xc000086f38 sp=0xc000086f08 pc=0x431311 runtime.mapassign_fast64(0x4b8080, 0xc0000ba390, 0x1)         \/usr\/local\/go\/src\/runtime\/map_fast64.go:101 +0x2c5 fp=0xc000086f70 sp=0xc000086f38 pc=0x410425 main.doWork(0x0)         \/home\/amos\/bearcove\/lox\/sample.go:13 +0x48 fp=0xc000086fa8 sp=0xc000086f70 pc=0x4abac8 main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:25 +0x58 fp=0xc000086fe0 sp=0xc000086fa8 pc=0x4abd78 runtime.goexit()         \/usr\/local\/go\/src\/runtime\/asm_amd64.s:1581 +0x1 fp=0xc000086fe8 sp=0xc000086fe0 pc=0x45d421 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:23 +0x4f  goroutine 1 [semacquire]: sync.runtime_Semacquire(0x0)         \/usr\/local\/go\/src\/runtime\/sema.go:56 +0x25 sync.(*WaitGroup).Wait(0xc000084728)         \/usr\/local\/go\/src\/sync\/waitgroup.go:130 +0x71 main.main()         \/home\/amos\/bearcove\/lox\/sample.go:29 +0xd8  goroutine 6 [runnable]: math\/rand.(*lockedSource).Int63(0xc000010030)         \/usr\/local\/go\/src\/math\/rand\/rand.go:387 +0xfe math\/rand.(*Rand).Int63(...)         \/usr\/local\/go\/src\/math\/rand\/rand.go:84 math\/rand.(*Rand).Int31(...)         \/usr\/local\/go\/src\/math\/rand\/rand.go:98 math\/rand.(*Rand).Int31n(0xc0000ba000, 0xa)         \/usr\/local\/go\/src\/math\/rand\/rand.go:133 +0x59 math\/rand.(*Rand).Intn(0x4b8080, 0xc0000ba390)         \/usr\/local\/go\/src\/math\/rand\/rand.go:171 +0x2e math\/rand.Intn(...)         \/usr\/local\/go\/src\/math\/rand\/rand.go:337 main.doWork(0x0)         \/home\/amos\/bearcove\/lox\/sample.go:12 +0x34 main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:25 +0x58 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:23 +0x4f exit status 2<\/code><\/pre>\n<p>  \u0425\u0430-\u0445\u0430! \u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c! \u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>  \u042d\u0442\u043e \u043d\u0435\u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0435\u0434\u044c map \u0432 Go \u043d\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b, \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 <a href=\"https:\/\/go.dev\/ref\/spec\" rel=\"nofollow noopener noreferrer\">\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u044f\u0437\u044b\u043a\u0430<\/a>.<\/p>\n<p>  \u0425\u043e\u0442\u044f \u043d\u0435\u0442, \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e. \u0420\u0430\u0437\u0432\u0435? \u041d\u043e \u0432\u0435\u0434\u044c <code>map<\/code> \u2014 \u044d\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f. \u0414\u0430, \u0442\u0430\u043a \u0438 \u0435\u0441\u0442\u044c, \u044d\u0442\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 <a href=\"https:\/\/go.dev\/blog\/maps\" rel=\"nofollow noopener noreferrer\">\u043f\u043e\u0441\u0442\u0435 \u0438\u0437 \u0431\u043b\u043e\u0433\u0430<\/a>!<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u043e\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a map \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0433\u043e\u0440\u0443\u0442\u0438\u043d, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d Mutex \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0438\u043f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 RWLock.<\/p>\n<p>  \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043d\u0430\u043b, \u0437\u0430\u0434\u0430\u0447\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 map.<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043a\u0430\u043d\u0430\u043b\u044b \u2014 \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u0430\u044f \u0438\u0434\u0435\u044f, \u043e\u043d\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0430\u043c:<\/p>\n<pre><code class=\"go\">package main  import (   \"math\/rand\"   \"sync\"    \"github.com\/davecgh\/go-spew\/spew\" )  func doWork(increments chan uint64) {   for i := 0; i &lt; 50000; i++ {     key := uint64(rand.Intn(10))     \/\/ we're just sending a \"unit of work\" to the updater goroutine     increments &lt;- key   } }  func main() {   var wg sync.WaitGroup    m := make(map[uint64]uint64)   var increments chan uint64    \/\/ this goroutine will be in charge of updating the map   go func() {     for increment := range increments {       m[increment] += 1     }   }()    for i := 0; i &lt; 2; i++ {     wg.Add(1)     go func() {       defer wg.Done()       doWork(increments)     }()   }    wg.Wait()   spew.Dump(m)    sum := uint64(0)   for _, v := range m {     sum += v   }   spew.Dump(sum) }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go fatal error: all goroutines are asleep - deadlock!  goroutine 1 [semacquire]: sync.runtime_Semacquire(0x0)         \/usr\/local\/go\/src\/runtime\/sema.go:56 +0x25 sync.(*WaitGroup).Wait(0xc000084728)         \/usr\/local\/go\/src\/sync\/waitgroup.go:130 +0x71 main.main()         \/home\/amos\/bearcove\/lox\/sample.go:38 +0x111  goroutine 6 [chan receive (nil chan)]: main.main.func1()         \/home\/amos\/bearcove\/lox\/sample.go:25 +0x59 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:24 +0x8f  goroutine 7 [chan send (nil chan)]: main.doWork(0x0)         \/home\/amos\/bearcove\/lox\/sample.go:13 +0x48 main.main.func2()         \/home\/amos\/bearcove\/lox\/sample.go:34 +0x58 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:32 +0xa5  goroutine 8 [chan send (nil chan)]: main.doWork(0x0)         \/home\/amos\/bearcove\/lox\/sample.go:13 +0x48 main.main.func2()         \/home\/amos\/bearcove\/lox\/sample.go:34 +0x58 created by main.main         \/home\/amos\/bearcove\/lox\/sample.go:32 +0xa5 exit status 2<\/code><\/pre>\n<p>  \u041e\u0439, \u043a\u0430\u043a\u0430\u044f \u043d\u0435\u0443\u043a\u043b\u044e\u0436\u0435\u0441\u0442\u044c. \u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e?<\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0442\u0435\u043a\u0430: \u0432 \u043d\u0435\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 nil chan, \u043d\u0443\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u043d\u0430\u043b\u0430, \u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0447\u0435\u0442\u044b\u0440\u0451\u043c \u0430\u043a\u0441\u0438\u043e\u043c\u0430\u043c \u043a\u0430\u043d\u0430\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u0436\u0435 \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u044b <a href=\"https:\/\/dave.cheney.net\/2014\/03\/19\/channel-axioms\" rel=\"nofollow noopener noreferrer\">\u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0441\u0442\u0435<\/a>, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0432 nil channel \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<p>  \u0412 \u043f\u043e\u0441\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u00ab\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u0430\u00bb, \u043d\u043e \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430. \u041d\u0430\u0432\u0435\u0440\u043d\u043e, \u043c\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0435\u0451 \u043d\u0435 \u0443\u0437\u043d\u0430\u0435\u043c.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u043c \u043d\u0430\u0448 \u0431\u0430\u0433:<\/p>\n<pre><code class=\"go\">\/\/ (cut)  func main() {   \/\/ (cut)    m := make(map[uint64]uint64)   \/\/ ?   increments := make(chan uint64)    \/\/ (cut) }<\/code><\/pre>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u043d\u043e!<\/p>\n<pre><code class=\"bash\">$ go run .\/sample.go (map[uint64]uint64) (len=10) {  (uint64) 9: (uint64) 9755,  (uint64) 5: (uint64) 10032,  (uint64) 0: (uint64) 10152,  (uint64) 1: (uint64) 10115,  (uint64) 7: (uint64) 10021,  (uint64) 4: (uint64) 9884,  (uint64) 2: (uint64) 9901,  (uint64) 3: (uint64) 9913,  (uint64) 8: (uint64) 9984,  (uint64) 6: (uint64) 10242 } (uint64) 99999<\/code><\/pre>\n<p>  \u041d\u043e \u043d\u0435\u0442. \u0427\u0442\u043e?<\/p>\n<p>  \u0421\u0443\u043c\u043c\u0430 \u043d\u0435 \u0440\u0430\u0432\u043d\u0430 \u0441\u0442\u0430 \u0442\u044b\u0441\u044f\u0447\u0430\u043c.<\/p>\n<p>  \u0410, \u043b\u0430\u0434\u043d\u043e, \u0437\u043d\u0430\u0447\u0438\u0442, \u0433\u0434\u0435-\u0442\u043e \u0435\u0434\u0438\u043d\u0438\u0446\u0430 \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0430\u0441\u044c, \u043d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0435\u0449\u0451 \u0440\u0430\u0437, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0441\u0443\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439!<\/p>\n<p>  \u0414\u0430 \u043d\u0435\u0442, \u043a\u043e\u043d\u0435\u0447\u043d\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c.<\/p>\n<p>  \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0451, \u043d\u043e \u043d\u0438 \u043e\u0434\u0438\u043d \u043c\u043d\u0435 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<pre><code class=\"go\">func main() { var wg sync.WaitGroup  m := make(map[uint64]uint64) increments := make(chan uint64) signal := make(chan struct{})  go func() { for increment := range increments { m[increment] += 1 } close(signal) }()  for i := 0; i &lt; 2; i++ { wg.Add(1) go func() { defer wg.Done() doWork(increments) }() }  \/\/ wait for workers... wg.Wait()  \/\/ signal end of \"units of work\" close(increments)  \/\/ wait for updater goroutine to finish &lt;-signal  spew.Dump(m)  sum := uint64(0) for _, v := range m { sum += v } spew.Dump(sum) }<\/code><\/pre>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439. \u041d\u0430\u0432\u0435\u0440\u043d\u043e. \u041c\u044b \u0434\u0430\u0436\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u043b\u0438 \u0443\u0442\u0435\u0447\u043a\u0443 \u043f\u0430\u043c\u044f\u0442\u0438! \u0420\u0430\u043d\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0430\u0441\u044c \u0431\u044b \u0432\u0435\u0447\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b \u00abincrements\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u0414\u043b\u044f \u044f\u0437\u044b\u043a\u0430 \u0441\u043e \u0441\u0431\u043e\u0440\u043a\u043e\u0439 \u043c\u0443\u0441\u043e\u0440\u0430 \u044d\u0442\u043e <em>\u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e<\/em> \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0442\u0435\u0447\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  \u041d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u043e \u0441\u0432\u043e\u0438\u0445 \u043f\u0435\u0447\u0430\u043b\u044f\u0445 \u0438 \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0447\u0435\u0441\u0442\u043d\u044b\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f\u043c. \u041d\u0438\u043a\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u00ab\u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c map \u0432 Go \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430\u00bb \u2014 \u044d\u0442\u043e \u0432\u044b\u0441\u0442\u0440\u0435\u043b \u0432 \u043d\u043e\u0433\u0443.<\/p>\n<p>  \u0415\u0441\u0442\u044c \u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b \u0432 \u043d\u043e\u0433\u0443 \u0432 Rust?<\/p>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c:<\/p>\n<pre><code class=\"rust\">use rand::Rng; use std::collections::HashMap;  fn do_work(m: &amp;mut HashMap&lt;u64, u64>) {     let mut rng = rand::thread_rng();     for _ in 0..100_000 {         let key: u64 = rng.gen_range(0..10);         *m.entry(key).or_default() += 1     } }  fn main() {     let mut m: HashMap&lt;u64, u64> = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;mut m));         s.spawn(|_| do_work(&amp;mut m));     })     .unwrap();      \/\/ format strings can capture arguments, as of Rust 1.58:     println!(\"map = {m:#?}\");     println!(\"sum = {}\", m.values().copied().sum::&lt;u64>()); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet error[E0499]: cannot borrow `m` as mutable more than once at a time   --> src\/main.rs:17:17    | 16 |         s.spawn(|_| do_work(&amp;mut m));    |                 ---              - first borrow occurs due to use of `m` in closure    |                 |    |                 first mutable borrow occurs here 17 |         s.spawn(|_| do_work(&amp;mut m));    |           ----- ^^^              - second borrow occurs due to use of `m` in closure    |           |     |    |           |     second mutable borrow occurs here    |           first borrow later used by call  For more information about this error, try `rustc --explain E0499`. error: could not compile `lox` due to previous error<\/code><\/pre>\n<p>  \u041d\u0435\u0442! \u0415\u0433\u043e \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c map \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>&amp;HashMap<\/code> (\u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438), \u043d\u043e \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f map \u043d\u0443\u0436\u0435\u043d <code>&amp;mut HashMap<\/code> (\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430), \u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d.<\/p>\n<p>  \u0422\u0430 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430 \u0438 \u0437\u0434\u0435\u0441\u044c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Mutex<\/code>:<\/p>\n<pre><code class=\"rust\">use parking_lot::Mutex; use rand::Rng; use std::collections::HashMap;  \/\/               ? fn do_work(m: &amp;Mutex&lt;HashMap&lt;u64, u64>>) {     let mut rng = rand::thread_rng();     for _ in 0..100_000 {         let key: u64 = rng.gen_range(0..10);         \/\/ ?         *m.lock().entry(key).or_default() += 1     } }  fn main() {     \/\/ note that `Default::default()` can still be used to build this type!     let m: Mutex&lt;HashMap&lt;u64, u64>> = Default::default();      crossbeam::scope(|s| {         s.spawn(|_| do_work(&amp;m));         s.spawn(|_| do_work(&amp;m));     })     .unwrap();      \/\/ and that we can take the map out of the mutex afterwards!     let m = m.into_inner();      println!(\"map = {m:#?}\");     println!(\"sum = {}\", m.values().copied().sum::&lt;u64>()); }<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet map = {     4: 19962,     2: 19952,     7: 20034,     1: 20209,     3: 20047,     6: 19820,     5: 20101,     0: 20398,     9: 19807,     8: 19670, } sum = 200000<\/code><\/pre>\n<p>  \u0418\u043b\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f map, \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u044d\u0442\u043e \u0441 \u0433\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438:<\/p>\n<pre><code class=\"rust\">use rand::Rng; use std::{collections::HashMap, sync::mpsc};  fn do_work(tx: mpsc::Sender&lt;u64>) {     let mut rng = rand::thread_rng();     for _ in 0..100_000 {         let key: u64 = rng.gen_range(0..10);         tx.send(key).unwrap();     } }  fn main() {     let mut m: HashMap&lt;u64, u64> = Default::default();      crossbeam::scope(|s| {         let (tx1, rx) = mpsc::channel();         let tx2 = tx1.clone();         let m = &amp;mut m;          s.spawn(move |_| {             while let Ok(key) = rx.recv() {                 *m.entry(key).or_default() += 1             }         });         s.spawn(move |_| do_work(tx1));         s.spawn(move |_| do_work(tx2));     })     .unwrap();      println!(\"map = {m:#?}\");     println!(\"sum = {}\", m.values().copied().sum::&lt;u64>()); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet map = {     2: 19931,     5: 20027,     3: 20023,     7: 19937,     8: 20007,     4: 20003,     6: 20122,     9: 20030,     1: 20013,     0: 19907, } sum = 200000<\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u00ab\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u00bb \u0438 \u00ab\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439\u00bb \u043a\u043e\u043d\u0446\u044b \u043a\u0430\u043d\u0430\u043b\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b: \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0440\u0438\u0451\u043c\u043d\u0438\u043a, \u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d, \u043e\u043d \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f, \u0430 \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0438 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u044b, \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u0436\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h2>\u041d\u043e \u043d\u0435 \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c<\/h2>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u043c\u043d\u043e\u0433\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 Rust \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 Rust \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>  \u042d\u0442\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043c\u0435\u043d\u044c\u0448\u0435! \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438\u0437 \u043d\u0435\u0433\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u044b! \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u043e\u0434\u043e\u0431\u0440\u044f\u0435\u043c\u044b\u0445 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c Rust.<\/p>\n<p>  \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0443 \u043c\u044b\u0441\u043b\u044c \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/fasterthanli.me\/articles\/frustrated-its-not-you-its-rust\" rel=\"nofollow noopener noreferrer\">Frustrated? It&#8217;s not you, it&#8217;s Rust<\/a>.<\/p>\n<p>  \u041d\u043e \u0432\u0430\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 \u0441\u0430\u043c\u044b\u0435 \u0441\u0442\u0440\u043e\u0433\u0438\u0435 \u044f\u0437\u044b\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u0438\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>  \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u044d\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<p>  \u041e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0438\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u0435\u0442 \u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u0441\u0435\u0431\u0435, \u043a\u043e\u0433\u0434\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0431\u0435\u0441\u043f\u043e\u0440\u044f\u0434\u043a\u0430.<\/p>\n<p>  \u041d\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b <i>\u0441 \u0447\u0435\u0433\u043e-\u0442\u043e<\/i> \u043d\u0430\u0447\u0430\u0442\u044c.<\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 Rust:<\/p>\n<pre><code class=\"rust\">fn add(a: u64, b: u64) -> u64 {     a - b }  fn main() {     dbg!(add(1, 3)); }<\/code><\/pre>\n<p>  <code>cargo check<\/code> \u043d\u0438\u0447\u0435\u0433\u043e \u043e \u043d\u0435\u0439 \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442. \u041d\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0441\u043a\u0430\u0437\u0430\u043b \u0431\u044b. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>add<\/code>, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u043d\u0430 \u0432\u044b\u0447\u0438\u0442\u0430\u0435\u0442.<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430:<\/p>\n<pre><code class=\"rust\">use parking_lot::Mutex;  fn main() {     let m: Mutex&lt;u64> = Default::default();      let mut guard = m.lock();     *guard += 1;      println!(\"m = {}\", m.lock()); }<\/code><\/pre>\n<p>  \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043e\u043d\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435:<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet (nothing is printed)<\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e\u0434 <a href=\"https:\/\/github.com\/rust-lang\/miri\" rel=\"nofollow noopener noreferrer\">miri<\/a> (\u0441 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0435\u0439) \u0432\u044b\u044f\u0432\u043b\u044f\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443:<\/p>\n<pre><code class=\"bash\">$ cargo clean; MIRIFLAGS=\"-Zmiri-disable-isolation\" cargo +nightly miri run    Compiling cfg-if v1.0.0    (cut)    Compiling lox v0.1.0 (\/home\/amos\/bearcove\/lox)     Finished dev [unoptimized + debuginfo] target(s) in 5.73s      Running `\/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/bin\/cargo-miri target\/miri\/x86_64-unknown-linux-gnu\/debug\/lox` error: deadlock: the evaluated program deadlocked    --> \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/thread_parker\/linux.rs:118:13     | 118 |             )     |             ^ the evaluated program deadlocked     |     = note: inside `parking_lot_core::thread_parker::imp::ThreadParker::futex_wait` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/thread_parker\/linux.rs:118:13     = note: inside `&lt;parking_lot_core::thread_parker::imp::ThreadParker as parking_lot_core::thread_parker::ThreadParkerT>::park` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/thread_parker\/linux.rs:66:13     = note: inside closure at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/parking_lot.rs:635:17     = note: inside `parking_lot_core::parking_lot::with_thread_data::&lt;parking_lot_core::parking_lot::ParkResult, [closure@parking_lot_core::parking_lot::park&lt;[closure@parking_lot::RawMutex::lock_slow::{closure#0}], [closure@parking_lot::RawMutex::lock_slow::{closure#1}], [closure@parking_lot::RawMutex::lock_slow::{closure#2}]>::{closure#0}]>` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/parking_lot.rs:207:5     = note: inside `parking_lot_core::parking_lot::park::&lt;[closure@parking_lot::RawMutex::lock_slow::{closure#0}], [closure@parking_lot::RawMutex::lock_slow::{closure#1}], [closure@parking_lot::RawMutex::lock_slow::{closure#2}]>` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot_core-0.9.1\/src\/parking_lot.rs:600:5     = note: inside `parking_lot::RawMutex::lock_slow` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot-0.12.0\/src\/raw_mutex.rs:262:17     = note: inside `&lt;parking_lot::RawMutex as parking_lot::lock_api::RawMutex>::lock` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/parking_lot-0.12.0\/src\/raw_mutex.rs:72:13     = note: inside `parking_lot::lock_api::Mutex::&lt;parking_lot::RawMutex, u64>::lock` at \/home\/amos\/.cargo\/registry\/src\/github.com-1ecc6299db9ec823\/lock_api-0.4.6\/src\/mutex.rs:214:9 note: inside `main` at src\/main.rs:9:24    --> src\/main.rs:9:24     | 9   |     println!(\"m = {}\", m.lock());     |                        ^^^^^^^^     = note: inside `&lt;fn() as std::ops::FnOnce&lt;()>>::call_once - shim(fn())` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/core\/src\/ops\/function.rs:227:5     = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::&lt;fn(), ()>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/sys_common\/backtrace.rs:123:18     = note: inside closure at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/rt.rs:145:18     = note: inside `std::ops::function::impls::&lt;impl std::ops::FnOnce&lt;()> for &amp;dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/core\/src\/ops\/function.rs:259:13     = note: inside `std::panicking::r#try::do_call::&lt;&amp;dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panicking.rs:485:40     = note: inside `std::panicking::r#try::&lt;i32, &amp;dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panicking.rs:449:19     = note: inside `std::panic::catch_unwind::&lt;&amp;dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panic.rs:136:14     = note: inside closure at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/rt.rs:128:48     = note: inside `std::panicking::r#try::do_call::&lt;[closure@std::rt::lang_start_internal::{closure#2}], isize>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panicking.rs:485:40     = note: inside `std::panicking::r#try::&lt;isize, [closure@std::rt::lang_start_internal::{closure#2}]>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panicking.rs:449:19     = note: inside `std::panic::catch_unwind::&lt;[closure@std::rt::lang_start_internal::{closure#2}], isize>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/panic.rs:136:14     = note: inside `std::rt::lang_start_internal` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/rt.rs:128:20     = note: inside `std::rt::lang_start::&lt;()>` at \/home\/amos\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/src\/rust\/library\/std\/src\/rt.rs:144:17  error: aborting due to previous error<\/code><\/pre>\n<p>  \u0418 \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e\u0435 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b, \u0438 \u0432 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>Mutex<\/code> \u0438\u0437 <code>parking_lot<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u044f\u0435\u0442, \u043d\u043e \u044f \u0441\u043e\u043c\u043d\u0435\u0432\u0430\u044e\u0441\u044c, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0446\u0435\u043b\u044b\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0434 miri. \u041e\u043d \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043a\u043e\u0434\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u0421\u0434\u0435\u043b\u0430\u043d\u043d\u0430\u044f \u043c\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043e\u0442\u043b\u043e\u0432\u0438\u043b Rust, \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u0430:<\/p>\n<pre><code class=\"rust\">use parking_lot::RwLock; use rand::Rng; use std::{     collections::HashMap,     sync::Arc,     time::{Duration, Instant}, };  #[derive(Default)] struct State {     entries: RwLock&lt;HashMap&lt;u64, u64>>, }  impl State {     fn update_state(&amp;self) {         let mut entries = self.entries.write();         let key = rand::thread_rng().gen_range(0..10);         *entries.entry(key).or_default() += 1;     }      fn foo(&amp;self) {         let entries = self.entries.read();         if entries.get(&amp;4).copied().unwrap_or_default() % 2 == 0 {             \/\/ do something         } else {             self.bar();         }     }      fn bar(&amp;self) {         let entries = self.entries.read();         if entries.get(&amp;2).is_some() {             \/\/ do something         } else {             \/\/ do something else         }     } }  fn main() {     let s: Arc&lt;State> = Default::default();      std::thread::spawn({         let s = s.clone();         move || loop {             std::thread::sleep(Duration::from_millis(1));             s.update_state();         }     });      let before = Instant::now();     for _ in 0..10_000 {         s.foo();     }     println!(\"All done in {:?}\", before.elapsed()); }<\/code><\/pre>\n<p>  \u0412\u0438\u0434\u0438\u0442\u0435 \u0431\u0430\u0433?<\/p>\n<p>  \u041f\u043e\u0445\u043e\u0436\u0435, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u2026<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet All done in 3.520651ms<\/code><\/pre>\n<p>  \u041d\u043e \u0435\u0441\u043b\u0438 \u0443\u0431\u0440\u0430\u0442\u044c <code>sleep<\/code> \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435\u2026<\/p>\n<pre><code class=\"rust\">\/\/ in main:     std::thread::spawn({         let s = s.clone();         move || loop {             s.update_state();         }     });<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet (nothing is ever printed)<\/code><\/pre>\n<p>  \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0435\u0449\u0451 \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0431\u0430\u0433, \u0442\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 <code>self.bar()<\/code> \u0432 <code>State::foo<\/code> \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0437\u0430\u043d\u043e\u0432\u043e. \u041e\u043d\u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code class=\"bash\">$ cargo run --quiet warning: associated function is never used: `bar`   --> src\/main.rs:26:8    | 26 |     fn bar(&amp;self) {    |        ^^^    |    = note: `#[warn(dead_code)]` on by default  All done in 1.891049988s<\/code><\/pre>\n<p>  \u0417\u0430 \u044d\u0442\u0443 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0435\u0441\u0442\u044c <em>\u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f<\/em> \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u044f (\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0437\u0430\u043d\u044f\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0446\u0438\u043a\u043b\u043e\u0432!), \u043d\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0430\u043c \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0443\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0451 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0434\u0435\u0441\u044f\u0442\u044c \u0442\u044b\u0441\u044f\u0447 \u0440\u0430\u0437 \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c \u0437\u0430 \u0434\u0432\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<p>  \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f <code>foo()<\/code> \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c <em>\u0434\u0432\u0435<\/em> \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043b\u044f <code>entries<\/code>.<\/p>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u0430:<\/p>\n<ul>\n<li><code>update_state<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0438<\/li>\n<li><code>foo<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f\u2026 (\u043e\u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f)<\/li>\n<li><code>update_state<\/code> \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/li>\n<li><code>update_state<\/code> \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0438<\/li>\n<li><code>foo<\/code> \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f<\/li>\n<li><code>foo<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>bar<\/code><\/li>\n<li><code>bar<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f<\/li>\n<li><code>bar<\/code> \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f<\/li>\n<li><code>foo<\/code> \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f<\/li>\n<\/ul>\n<p>  \u0410 \u044d\u0442\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u0430:<\/p>\n<ul>\n<li><code>foo<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f<\/li>\n<li><code>update_state<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0438\u2026 (\u043e\u043d\u0430 \u043f\u043e\u043a\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f)<\/li>\n<li><code>foo<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>bar<\/code><\/li>\n<li><code>bar<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f\u2026 (\u043e\u043d\u0430 \u043f\u043e\u043a\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f)<\/li>\n<\/ul>\n<p>  \u0418 \u043d\u0438 <code>bar<\/code>, \u043d\u0438 <code>update_state<\/code> \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u00ab\u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f\u00bb, \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>foo<\/code> \u0432\u044b\u0437\u0432\u0430\u043b\u0430 <code>bar<\/code>, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e <em>\u0434\u0432\u0435<\/em> \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0447\u0442\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0438\u0437 <code>foo<\/code> (\u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0435\u0451 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f).<\/p>\n<p>  \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0436\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u00abRWR\u00bb, \u0438 \u044d\u0442\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430. \u00abWRR\u00bb \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0431\u044b \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u043a\u0430\u043a \u0438 \u00abRRW\u00bb, \u043d\u043e \u043d\u0435 \u00abRWR\u00bb.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u043e\u0442 \u043e\u0448\u0438\u0431\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 Rust.<\/p>\n<p>  \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u0431\u044b\u043b\u0430 \u043c\u0435\u043d\u044c\u0448\u0435!<\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c <code>entries<\/code> \u0438\u0437 <code>State<\/code> \u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0435\u0451:<\/p>\n<pre><code class=\"rust\">use parking_lot::RwLock; use rand::Rng; use std::{collections::HashMap, sync::Arc, time::Instant};  #[derive(Default)] struct State {}  impl State {     fn update_state(&amp;self, entries: &amp;mut HashMap&lt;u64, u64>) {         let key = rand::thread_rng().gen_range(0..10);         *entries.entry(key).or_default() += 1;     }      fn foo(&amp;self, entries: &amp;HashMap&lt;u64, u64>) {         if entries.get(&amp;4).copied().unwrap_or_default() % 2 == 0 {             \/\/ do something         } else {             self.bar(entries);         }     }      fn bar(&amp;self, entries: &amp;HashMap&lt;u64, u64>) {         if entries.get(&amp;2).is_some() {             \/\/ do something         } else {             \/\/ do something else         }     } }  fn main() {     let entries: Arc&lt;RwLock&lt;HashMap&lt;u64, u64>>> = Default::default();     let s: Arc&lt;State> = Default::default();      std::thread::spawn({         let s = s.clone();         let entries = entries.clone();         move || loop {             s.update_state(&amp;mut entries.write());         }     });      let before = Instant::now();     for _ in 0..10_000 {         s.foo(&amp;entries.read());     }     println!(\"All done in {:?}\", before.elapsed()); }<\/code><\/pre>\n<p>  \u041d\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u0443\u0447\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044e.<\/p>\n<p>  \u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u0443\u044e struct, <code>ReadLockedState<\/code>, \u0438\u043c\u0435\u044e\u0449\u0443\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0442\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"rust\">use parking_lot::{RwLock, RwLockReadGuard}; use rand::Rng; use std::{collections::HashMap, sync::Arc, time::Instant};  #[derive(Default)] struct State {     entries: Arc&lt;RwLock&lt;HashMap&lt;u64, u64>>>, }  impl State {     fn update_state(&amp;self) {         let mut entries = self.entries.write();         let key: u64 = rand::thread_rng().gen_range(0..10);         *entries.entry(key).or_default() += 1;     }      fn read(&amp;self) -> ReadLockedState&lt;'_> {         ReadLockedState {             entries: self.entries.read(),         }     } }  struct ReadLockedState&lt;'a> {     entries: RwLockReadGuard&lt;'a, HashMap&lt;u64, u64>>, }  impl ReadLockedState&lt;'_> {     fn foo(&amp;self) {         if self.entries.get(&amp;4).copied().unwrap_or_default() % 2 == 0 {             \/\/ do something         } else {             self.bar();         }     }      fn bar(&amp;self) {         if self.entries.get(&amp;2).is_some() {             \/\/ do something         } else {             \/\/ do something else         }     } }  fn main() {     let s: Arc&lt;State> = Default::default();      std::thread::spawn({         let s = s.clone();         move || loop {             s.update_state();         }     });      let before = Instant::now();     for _ in 0..10_000 {         s.read().foo();     }     println!(\"All done in {:?}\", before.elapsed()); }<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"bash\">$ cargo run --quiet All done in 1.96135045s<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043c\u043d\u0435 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u043d\u043e \u043e\u043d\u043e \u0442\u043e\u0436\u0435 \u043d\u0435\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0432 <code>State<\/code> \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044f, \u0438 \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a \u043d\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u0438 \u0438\u0437 <code>ReadLockedState<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u0430\u043c \u0438\u043b\u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043d\u0438\u0445 \u0432\u0441\u0435, \u0438\u043b\u0438 \u0438\u043c\u0435\u0442\u044c \u0442\u0430\u043c <code>&amp;'a State<\/code> (\u0447\u0442\u043e \u0441\u043d\u043e\u0432\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u0430 <code>self.state.entries.read()<\/code>), \u0438\u043b\u0438 \u0440\u0430\u0437\u0431\u0438\u0442\u044c <code>State<\/code> \u043d\u0430 \u0434\u0432\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b: \u043e\u0434\u043d\u0443 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 <code>RwLock<\/code>, \u0434\u0440\u0443\u0433\u0443\u044e \u0431\u0435\u0437 (\u0438 struct <code>ReadLockedState<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c <code>&amp;'a ReadOnlyState<\/code> \u0438 <code>RwLockReadGuard&lt;'a, ProtectedState><\/code>, \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435).<\/p>\n<p>  \u041d\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044f <code>Arc&lt;RwLock&lt;T>><\/code>, <br \/>  \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e. \u041a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0449\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0444\u0438\u0447\u0443 \u044f\u0437\u044b\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435: \u044f \u043d\u0435 \u0445\u043e\u0447\u0443, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 <code>RwLock<\/code> \u0431\u044b\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435, \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438:<\/p>\n<pre><code class=\"rust\">impl State {     fn foo(&amp;self) {         let entries = self.entries.read();         if entries.get(&amp;4).copied().unwrap_or_default() % 2 == 0 {             \/\/ do something         } else {             self.bar();         }     }      fn bar(&amp;self) {         \/\/ ? error! cannot call `self.entries.read()` because `bar()` can be         \/\/ called by `foo()`, which is already holding a read lock to         \/\/ `self.entries`.         let entries = self.entries.read();         if entries.get(&amp;2).is_some() {             \/\/ do something         } else {             \/\/ do something else         }     } }<\/code><\/pre>\n<p>  Rust \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u044d\u0442\u043e\u0433\u043e, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043f\u043e\u043a\u0430.<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/654697\/\"> https:\/\/habr.com\/ru\/post\/654697\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/tf\/u5\/vi\/tfu5vinauktrvp3jxgqwbso1lfe.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/tf\/u5\/vi\/tfu5vinauktrvp3jxgqwbso1lfe.jpeg\" data-blurred=\"true\"\/><\/div>\n<p>  \u041c\u043d\u0435 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u044f\u0437\u044b\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0443\u0436\u0435 \u043d\u0435 \u0442\u0430\u043a \u0441\u0438\u043b\u044c\u043d\u043e, \u0438 \u043d\u0435 \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043c\u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u0430, \u0441\u043a\u043e\u0440\u0435\u0435, \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043c\u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c <em>\u043d\u0435<\/em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442.<\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0440\u0435\u0434\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0441\u0430\u043c\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c: \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 C++, \u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043d\u0430 C, \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u044f\u0437\u044b\u043a \u043f\u043e\u043b\u043e\u043d \u043f\u043e \u0422\u044c\u044e\u0440\u0438\u043d\u0433\u0443 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u0430\u043a\u0438\u043c \u0431\u044b \u043d\u0438 \u0431\u044b\u043b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0432\u044b \u043e\u0431\u0449\u0430\u0435\u0442\u0435\u0441\u044c \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u043e\u0439. \u0412\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0435\u0433\u043e \u043f\u0430\u043c\u044f\u0442\u0438 (\u0438 \u0435\u0451 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e), \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u043a \u043d\u0435\u043c\u0443 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0435\u0439, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<blockquote><p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, <a href=\"https:\/\/github.com\/xoreaxeaxeax\/movfuscator\" rel=\"nofollow noopener noreferrer\">\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e<\/a> \u043b\u0438\u0448\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>mov<\/code>.<\/p><\/blockquote>\n<p>  \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438: \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430. \u042f\u0437\u044b\u043a Java \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0441\u0432\u043e\u0435\u0439 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e\u0441\u0442\u044c\u044e: \u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c \u043e\u043d \u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0439.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043e\u0442\u043b\u0430\u0434\u043a\u043e\u043f\u0440\u0438\u0433\u043e\u0434\u043d\u043e\u0441\u0442\u044c (\u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u043d\u0435\u0442, \u0442\u043e \u0435\u0433\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c) \u0438 \u0434\u044e\u0436\u0438\u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u0438 \u00ab\u0432\u044b\u0431\u043e\u0440\u0435 \u044f\u0437\u044b\u043a\u0430\u00bb.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-330462","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=330462"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330462\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=330462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=330462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=330462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}