tag:crieit.net,2005:https://crieit.net/users/block_cube_lib/feed blockの投稿 - Crieit Crieitでユーザーblockによる最近の投稿 2023-05-11T12:46:43+09:00 https://crieit.net/users/block_cube_lib/feed tag:crieit.net,2005:PublicArticle/18430 2023-05-11T12:46:43+09:00 2023-05-11T12:46:43+09:00 https://crieit.net/posts/Rust-const-generics Rustのconst genericsの引数によって型の定義を変える(っぽいこと) <p>若干釣りっぽいタイトルです</p> <h2 id="やりたいこと"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8">やりたいこと</a></h2> <p><code>Vector<T, const D: usize></code>のような要素型と次元数を受け取る<code>Vector</code>型があったとして</p> <pre><code class="rust">// x, yを持つ let v2 = Vector::<f32, 2> { x: 1.1, y: 2.2 }; // x, y, zを持つ let v3 = Vector::<f32, 3> { x: 1.1, y: 2.2, z: 3.3, }; // x, y, z, wを持つ let v4 = Vector::<f32, 4> { x: 1.1, y: 2.2, z: 3.3, w: 3.3, }; // 要素数5の配列を持つ let v5 = Vector::<f32, 5> { elements: [1.1, 2.2, 3.3, 4.4, 5.5], }; </code></pre> <p>のように<code>Vector::<T, 2></code>は<code>x</code>, <code>y</code>を持つ、<br /> <code>Vector::<T, 3></code>は<code>x</code>, <code>y</code>, <code>z</code>を持つ、<br /> <code>Vector::<T, 4></code>は<code>x</code>, <code>y</code>, <code>z</code>, <code>w</code>を持つ、<br /> <code>D >= 5</code>となる<code>Vector::<T, D></code>は配列<code>elements: [T; D]</code>を持つ、<br /> というような実装にしたい。</p> <h2 id="実装"><a href="#%E5%AE%9F%E8%A3%85">実装</a></h2> <p>実装全文。<br /> 重要なのは<code>VectorTypeHolder</code>と<code>VectorTypeResolver</code>です。</p> <pre><code class="rust">use std::marker::PhantomData; pub struct Vector2<T> { pub x: T, pub y: T, } pub struct Vector3<T> { pub x: T, pub y: T, pub z: T, pub w: T, } pub struct Vector4<T> { pub x: T, pub y: T, pub w: T, } pub struct ArrayWrapper<T, D> { elements: [T; D], } pub trait VectorTypeHolder<T, const D: usize> { type Vector; } pub struct VectorTypeResolver<T, const D: usize> { _marker: PhantomData<fn() -> [T; D]>, } impl<T> VectorTypeHolder<T, 2> for VectorTypeResolver<T, 2> { type Vector = Vector2<T>; } impl<T> VectorTypeHolder<T, 3> for VectorTypeResolver<T, 3> { type Vector = Vector3<T>; } impl<T> VectorTypeHolder<T, 4> for VectorTypeResolver<T, 4> { type Vector = Vector4<T>; } impl<T> VectorTypeHolder<T, 5> for VectorTypeResolver<T, N> { type Vector = ArrayWrapper<T, 5>; } pub type Vector<T, const D: usize> = <VectorTypeResolver<T, D> as VectorTypeHolder<T, D>>::Vector; </code></pre> <h2 id="解説"><a href="#%E8%A7%A3%E8%AA%AC">解説</a></h2> <p><code>Vector2</code>, <code>Vector3</code>, <code>Vector4</code>と配列をラップした<code>ArrayWrapper</code>はそれぞれ2~4次元の時に使用する型と5次元以上のときに使用する型です。<br /> 下記の<code>VectorTypeHolder</code>は要素型と次元数をgenerics引数として受けとり<code>Vector</code>という関連型を持つtraitです。</p> <pre><code class="rust">pub trait VectorTypeHolder<T, const D: usize> { type Vector; } </code></pre> <p>ここから<code>VectorTypeHolder</code>と型を取り出すために<code>VectorTypeResolver</code>という型を定義し、<code>VectorTypeResolver</code>に対して<code>VectorTypeHolder</code>を実装します。</p> <pre><code class="rust">pub struct VectorTypeResolver<T, const D: usize> { _marker: PhantomData<fn() -> [T; D]>, } </code></pre> <p><code>VectorTypeResolver</code>が持つ<code>_marker</code>はジェネリクス引数を消費するだけのものなので無視して大丈夫です。気になる方は<code>PhantomData</code>を調べてください。<br /> traitを実装するときconst genericsの値を指定して実装することができるため以下のようにDが2のときのみの実装を行うことができます。</p> <pre><code class="rust">impl<T> VectorTypeHolder<T, 2> for VectorTypeResolver<T, 2> { type Vector = Vector2<T>; } </code></pre> <p>同様に<code>VectorTypeHolder::Vector</code>がDが3,4のときに<code>Vector3</code>, <code>Vector4</code>を、Dが5のときは<code>ArrayWrapper<T, 5></code>となるように実装します。</p> <pre><code class="rust">impl<T> VectorTypeHolder<T, 2> for VectorTypeResolver<T, 2> { type Vector = Vector2<T>; } impl<T> VectorTypeHolder<T, 3> for VectorTypeResolver<T, 3> { type Vector = Vector3<T>; } impl<T> VectorTypeHolder<T, 4> for VectorTypeResolver<T, 4> { type Vector = Vector4<T>; } impl<T> VectorTypeHolder<T, 5> for VectorTypeResolver<T, 5> { type Vector = ArrayWrapper<T, 5>; } </code></pre> <p>最後に<code>Vector<T, D></code>として型を取得できるように</p> <pre><code class="rust">pub type Vector<T, const D: usize> = <VectorTypeResolver<T, D> as VectorTypeHolder<T, D>>::Vector; </code></pre> <p>と型エイリアスを定義します。</p> <p>ここまででで最初のやりたいことが実現できるようになりました。</p> <h2 id="Dが5より大きい場合"><a href="#D%E3%81%8C5%E3%82%88%E3%82%8A%E5%A4%A7%E3%81%8D%E3%81%84%E5%A0%B4%E5%90%88">Dが5より大きい場合</a></h2> <p>実はこの実装だとD > 5の場合にコンパイルエラーになります。<br /> それを解消するには</p> <pre><code class="rust">impl<T> VectorTypeHolder<T, 6> for VectorTypeResolver<T, 6> { type Vector = ArrayWrapper<T, 6>; } impl<T> VectorTypeHolder<T, 7> for VectorTypeResolver<T, 7> { type Vector = ArrayWrapper<T, 7>; } impl<T> VectorTypeHolder<T, 8> for VectorTypeResolver<T, 8> { type Vector = ArrayWrapper<T, 8>; } // // 以下D >= 9の実装が続く // </code></pre> <p>というように使用する分<code>VectorTypeHolder</code>の実装をする必要があります。<br /> <code>seq_macro</code>クレートの<code>seq</code>マクロを使用すると以下のようにまとめて実装できます。</p> <pre><code class="rust">// use seq_macro::seq; seq!(N in 5..256 { impl<T> VectorTypeHolder<T, N> for VectorTypeResolver<T, N> { type Vector = ArrayWrapper<T, N>; } }); </code></pre> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://recruit.cct-inc.co.jp/tecblog/rust/template-rust/">テンプレートの特殊化(Rust版)</a></p> block tag:crieit.net,2005:PublicArticle/16676 2021-02-08T15:02:37+09:00 2021-02-08T15:02:37+09:00 https://crieit.net/posts/c8733a3222e2ae25ef3e4c2cc45af58c 黒い画面に文字を出すことがゲーム開発の何に使えるのか(役立つのか) <p>この記事と全く同じ内容を自分のブログにも投稿しています。</p> <hr /> <h2 id="前置き"><a href="#%E5%89%8D%E7%BD%AE%E3%81%8D">前置き</a></h2> <p>「ゲーム作りたいからプログラミング勉強しよう」という動機でプログラミングを始めたけれど<br /> 「ずっと黒い画面に文字出してばっかりでつまらん。これゲーム開発の何の役に立つんだ」ってなってる人向けです。<br /> 最初からゲームエンジンを使っている人は対象外。</p> <p>黒い画面に文字を出すのはHello Worldとかのことです。<br /> C++ならこういうコード。</p> <pre><code class="cpp">#include <iostream> int main() { std::cout << "Hello World" << std::endl; } </code></pre> <p>上のコードを実行すると黒い画面に<code>Hello World</code>と出力されます。</p> <p>まあこんなことができたところでこんなんゲーム関係ないってなりますよね。<br /> それが何に使えて何の役に立つのかって話です。</p> <h2 id="セーブ機能を作るのに使える"><a href="#%E3%82%BB%E3%83%BC%E3%83%96%E6%A9%9F%E8%83%BD%E3%82%92%E4%BD%9C%E3%82%8B%E3%81%AE%E3%81%AB%E4%BD%BF%E3%81%88%E3%82%8B">セーブ機能を作るのに使える</a></h2> <p>上のコードだと「黒い画面」に「Hello Worldという文字列を出力する」という処理になるわけですが、<br /> 出力先を「黒い画面」から「ファイル」に変更すれば、「ファイル」に「Hello Worldという文字列を出力する」という処理になりますし、<br /> 更に出力内容を「ゲームを復元するのに必要なデータ」にすれば「ファイル」に「ゲームを復元するのに必要なデータ出力する」という処理となり、つまりはセーブ処理になります。</p> <h2 id="デバッグに役立つ"><a href="#%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%AB%E5%BD%B9%E7%AB%8B%E3%81%A4">デバッグに役立つ</a></h2> <p>ゲームの開発中に「この処理にちゃんと到達しているのか」「今のプレイヤーのHPはいくつか」などを確認したいことがあります。そのときに文字列を出力する方法を知っていれば知りたい情報を画面に出すことができます。<br /> 「プレイヤーのHPくらいゲーム画面に表示すればいいでしょ」ってなるかも知れませんが、ゲーム画面に表示する機能の実装前での確認や、画面に表示しているHPと実際のHPが本当に同じかなどのチェックに使えます。</p> <p>「printfデバッグ」でググるといろんな情報が出てきます。否定的な意見も多いと思いますが結構馬鹿にできないです。</p> <h2 id="あとがき"><a href="#%E3%81%82%E3%81%A8%E3%81%8C%E3%81%8D">あとがき</a></h2> <p>例が少ないとは思いますがこんなことに役立つよって話でした。<br /> 自分の経験だけで言えば黒い画面に向かっていた時間はほぼ全部ゲーム開発に活きています。</p> block tag:crieit.net,2005:PublicArticle/16019 2020-07-28T20:55:49+09:00 2020-07-28T20:56:40+09:00 https://crieit.net/posts/Visual-Studio-Code-UnityEngine-UI Visual Studio Code内でUnityEngine.UIなどへの参照ができない(インテリジェンスが働かない)場合の修正方法 <p>Unity 2019.3.10f1で確認しています。<br /> 2019.4以降では解決しているかもしれません。</p> <h2 id="発生する現象"><a href="#%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B%E7%8F%BE%E8%B1%A1">発生する現象</a></h2> <p>Unity2019でプロジェクトを作成するとUnityではエラーが発生していないにも関わらず、Visual Studio Code内でUsing UnityEngine.UIなどへ参照ができない現象が発生します。</p> <p><a href="https://crieit.now.sh/upload_images/2c49c6834fd352a33cedc850cc0eab665f201218275ca.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2c49c6834fd352a33cedc850cc0eab665f201218275ca.png?mw=700" alt="image" /></a><br /> ↑画像のようにUIの下に赤線が表示される</p> <p>UnityEngin.UIにあるImageも正常に参照できておらずimage.まで打っても候補が表示されない。<br /> <a href="https://crieit.now.sh/upload_images/053dd0bbc7386336b12c79ffa17d4f315f20122ddff4b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/053dd0bbc7386336b12c79ffa17d4f315f20122ddff4b.png?mw=700" alt="image" /></a></p> <h3 id="表示されるエラー内容"><a href="#%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E3%82%A8%E3%83%A9%E3%83%BC%E5%86%85%E5%AE%B9">表示されるエラー内容</a></h3> <p><a href="https://crieit.now.sh/upload_images/3a4a5795e73e6e46b9335ed1172d253d5f2011105d415.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3a4a5795e73e6e46b9335ed1172d253d5f2011105d415.png?mw=700" alt="image" /></a></p> <pre><code>Using directive is unnecessary. [Assembly-CSharp]csharp(IDE0005) Unnecessary using directive. [Assembly-CSharp]csharp(CS8019) The type or namespace name 'UI' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?) [Assembly-CSharp]csharp(CS0234) </code></pre> <h2 id="解決方法"><a href="#%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95">解決方法</a></h2> <p>Package ManagerからVisual Studio Code Editorのパッケージのバージョンを上げる<br /> メニューのWindowからPackage Managerを開きVisual Studio Code Editorを選択します。<br /> <a href="https://crieit.now.sh/upload_images/9cae6712694566728ba164b07b0de6a55f2011a170923.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9cae6712694566728ba164b07b0de6a55f2011a170923.png?mw=700" alt="image" /></a><a href="https://crieit.now.sh/upload_images/efb9498b362bae3503042cf8d346d1d45f2011ac96429.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/efb9498b362bae3503042cf8d346d1d45f2011ac96429.png?mw=700" alt="image" /></a><br /> 初期は1.1.4になっているはずなので、1.2.0を選び右下の<strong>Update to 1.2.0</strong>ボタンを押して更新します。</p> <p>更新後はVisual Studio Codeを再起動してください。</p> <p>再起動後も参照ができないままのときは、少し時間をおいてからVisual Studio Codeを再起動してみてください。</p> block tag:crieit.net,2005:PublicArticle/15524 2019-11-01T20:31:16+09:00 2019-11-01T20:34:07+09:00 https://crieit.net/posts/crate-feature 依存先のcrateのfeatureを指定する方法 <h1 id="依存先のcrateのfeatureを有効にする方法"><a href="#%E4%BE%9D%E5%AD%98%E5%85%88%E3%81%AEcrate%E3%81%AEfeature%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95">依存先のcrateのfeatureを有効にする方法</a></h1> <h2 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h2> <p><code>cargo build --features="grpcio/openssl"</code>で<code>grpcio</code>の<code>openssl</code>を有効にできる。</p> <hr /> <p>Cargo.tomlが下記のようになっていれば<br /> <code>cargo build --features="openssl"</code>で同じことができる。</p> <pre><code class="toml">[features] openssl = ["grpcio/openssl"] [dependencies] grpcio = "0.4.4" </code></pre> <h2 id="やりたかったこと"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8">やりたかったこと</a></h2> <p><code>grpcio</code>というcrateで<code>featueres = ["openssl"]</code> を指定してやることができる。</p> <p><code>cargo build</code>のようにfeaturesを指定しなかったときは<code>grpcio</code>のfeaturesを有効にしたくない。<br /> <code>cargo build --features=openssl</code>などしたときだけ<code>grpcio</code>の<code>openssl</code>を有効にしたい。</p> <h2 id="ドキュメントに書いてあった"><a href="#%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AB%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%82%E3%81%A3%E3%81%9F">ドキュメントに書いてあった</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section">https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section</a></p> <p>以下引用</p> <pre><code># Features can be used to reexport features of other packages. The `session` # feature of package `awesome` will ensure that the `session` feature of the # package `cookie` is also enabled. session = ["cookie/session"] </code></pre> <p>ここに気づかずに数時間無駄にした。</p> block tag:crieit.net,2005:PublicArticle/15373 2019-09-03T14:51:14+09:00 2020-02-10T16:27:29+09:00 https://crieit.net/posts/Iris-5d6dff5219e6f Iris無線化ログ <h1 id="Iris無線化ログ"><a href="#Iris%E7%84%A1%E7%B7%9A%E5%8C%96%E3%83%AD%E3%82%B0">Iris無線化ログ</a></h1> <p><a href="https://crieit.net/posts/Iris-5d1f055fc8655">Irisビルドログ(完成)</a><br /> ↑前回の記事</p> <h2 id="何をしたのか"><a href="#%E4%BD%95%E3%82%92%E3%81%97%E3%81%9F%E3%81%AE%E3%81%8B">何をしたのか</a></h2> <p>前回までに作ったIrisをBLE Micro Proを使用して無線化。</p> <h2 id="使用したもの"><a href="#%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%82%82%E3%81%AE">使用したもの</a></h2> <ul> <li>完成済みIris</li> <li><a target="_blank" rel="nofollow noopener" href="https://nogikes.booth.pm/items/1177319">BLE Micro Pro</a> ×2</li> <li><a target="_blank" rel="nofollow noopener" href="https://nogikes.booth.pm/items/1241103">CR1632基板キット</a> (2個入りなので1個で良い。結果的に2つ買うことになりましたが)</li> <li><a target="_blank" rel="nofollow noopener" href="https://yushakobo.jp/shop/a01mc-00/">スプリングピンヘッダ</a> (普通のピンヘッダでもよいが圧倒的にスプリングピンヘッダがおすすめ)</li> <li>はんだ付けセット</li> <li>導線的なやつ</li> <li>絶縁できそうなテープ</li> </ul> <h2 id="制作過程"><a href="#%E5%88%B6%E4%BD%9C%E9%81%8E%E7%A8%8B">制作過程</a></h2> <h3 id="ファームウェア作成"><a href="#%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2%E4%BD%9C%E6%88%90">ファームウェア作成</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/sekigon-gonnoc/qmk_firmware">sekigon-gonnoc/qmk_firmware</a><br /> こちらにBLE Micro Proに対応したキーボードのファームウェアがいくつかありますが、Irisのものはなかったので自分で作る必要がありました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/sekigon-gonnoc/BLE-Micro-Pro">sekigon-gonnoc/BLE-Micro-Pro</a>に</p> <blockquote> <p>qmk_firmware/keyboard/ble_micro_testが一体型、qmk_firmware/keyboard/ergo42_ble, helix_bleなどが左右分離型のサンプルとなっています。</p> </blockquote> <p>とあるので<code>qmk_firmware/keyboard/ergo42_ble</code>や<code>qmk_firmware/keyboard/helix_ble</code>を参考にIris用のファームウェアを作成しました。<br /> 作成したと言っても参考元をすべてコピーしてきて必要そうな箇所(ファイル名とかキーボードの名前とか)を書き換えただけです。</p> <h3 id="電池基板組み立て"><a href="#%E9%9B%BB%E6%B1%A0%E5%9F%BA%E6%9D%BF%E7%B5%84%E3%81%BF%E7%AB%8B%E3%81%A6">電池基板組み立て</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/sekigon-gonnoc/BLE-Micro-Pro/CoinCcellHolder">sekigon-gonnoc/BLE-Micro-Pro/CoinCellHolder</a><br /> こちらの注意点と他の方の組み立てログを見ながら電池基盤を組立てました。<br /> 電池基盤の裏面はテープを貼って絶縁しています。</p> <h3 id="電池基盤をBLE Micro Proに接続する"><a href="#%E9%9B%BB%E6%B1%A0%E5%9F%BA%E7%9B%A4%E3%82%92BLE+Micro+Pro%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B">電池基盤をBLE Micro Proに接続する</a></h3> <p>導線で直接つなげてはんだ付けしました。</p> <h3 id="ファームウェア書き込み"><a href="#%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF">ファームウェア書き込み</a></h3> <p>作成したファームウェアを書き込みます。<br /> リセットスイッチを押しながらUSBを刺さなかったせいで、makeは成功するけど書き込みに失敗するということがありました。</p> <h3 id="左右のキーボードを接続する"><a href="#%E5%B7%A6%E5%8F%B3%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%82%92%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B">左右のキーボードを接続する</a></h3> <p>左右分割キーボードの場合はPCとキーボードよりも先に左右のキーボードを接続する必要があります。多分。<br /> 何故か全然つながらなくて苦労しました。<br /> 両方ともシリアル接続して<code>del 0</code>して<code>adv</code>したら接続できたので、おそらく組立前にPCとの接続テストをやっていたせいでid=0にPCが登録されていたのが原因だったのでしょう。</p> <hr /> <p>シリアル接続に使用したコマンドメモ<br /> <code>ls -l /dev/tty.*</code><br /> <code>sudo cu -l /dev/tty.XXXX</code></p> <h3 id="PCと接続する"><a href="#PC%E3%81%A8%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B">PCと接続する</a></h3> <p>左右のキーボードの接続が終わればようやくPCとの接続です。<br /> <code>restart_advertising_wo_whitelist()</code>を呼び出すキー(<code>AD_WO_L</code>が割り当てられたキー)を押してPC側から接続するキーボードを選べば接続できるはずです。</p> <h3 id="完成までにやらかしたこと"><a href="#%E5%AE%8C%E6%88%90%E3%81%BE%E3%81%A7%E3%81%AB%E3%82%84%E3%82%89%E3%81%8B%E3%81%97%E3%81%9F%E3%81%93%E3%81%A8">完成までにやらかしたこと</a></h3> <p>最初に買った電池基盤は付属のスイッチがやたらと固くて、力を込めてOFFにしようとしたら折れました。<br /> もう一個買いました。<br /> 折るくらいなら先に問い合わせたほうが良かった。<br /> 他の電池基盤を組立てている最中に表面実装のダイオードをふっ飛ばしてなくしてしまったので、結果的に2セット買ったのが役に立ちました。</p> <hr /> <p>右手のキーボードのBLE Micro Proを裏表逆につけていました。<br /> <a target="_blank" rel="nofollow noopener" href="https://yushakobo.jp/shop/a01mc-00/">スプリングピンヘッダ</a>を使用していたのではんだ付けをしておらず助かりました。<br /> そうでなければ(精神的に)死んでました。</p> <h2 id="使用風景"><a href="#%E4%BD%BF%E7%94%A8%E9%A2%A8%E6%99%AF">使用風景</a></h2> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自分の席から離れてるときの作業環境。コードレスになってスッキリ。 <a target="_blank" rel="nofollow noopener" href="https://t.co/A5mWBHJPkI">pic.twitter.com/A5mWBHJPkI</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1168348456714260480?ref_src=twsrc%5Etfw">September 2, 2019</a></blockquote> <hr /> <h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1> <p>無線キーボード最高!!</p> <hr /> <p>現在の設定。<br /> <code>BLE_NUS_MIN_INTERVAL</code> = 30<br /> <code>BLE_NUS_MAX_INTERVAL</code> = 50<br /> <code>BLE_HID_MAX_INTERVAL</code> = 30<br /> <code>BLE_HID_SLAVE_LATENCY</code> = 4<br /> まだ偶にキーが連続で入力されてしまうことがあるので設定を変えるかもしれません。</p> <hr /> <p><strong>この記事は無線化したIris(Iris BLE)で書かれました。</strong></p> block tag:crieit.net,2005:PublicArticle/15205 2019-07-05T17:07:59+09:00 2019-09-03T14:52:57+09:00 https://crieit.net/posts/Iris-5d1f055fc8655 Irisビルドログ(完成) <h1 id="Irisビルドログ その2"><a href="#Iris%E3%83%93%E3%83%AB%E3%83%89%E3%83%AD%E3%82%B0+%E3%81%9D%E3%81%AE2">Irisビルドログ その2</a></h1> <p><a href="https://crieit.net/posts/Iris">前回</a>の続きです<br /> 前回はキースイッチをはめてはんだ付けする前まで進みました。</p> <p>前回は4月23日。<br /> 今回は5月29日から。<br /> 一ヶ月以上空いているのは会社の部活で組み立てしているからです。</p> <p>無線化しました → <a href="https://crieit.net/posts/Iris-5d6dff5219e6f">Iris無線化ログ</a></p> <h2 id="組み立て過程"><a href="#%E7%B5%84%E3%81%BF%E7%AB%8B%E3%81%A6%E9%81%8E%E7%A8%8B">組み立て過程</a></h2> <h3 id="5月29日"><a href="#5%E6%9C%8829%E6%97%A5">5月29日</a></h3> <p>キースイッチのはんだ付けをして</p> <blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">キースイッチのはんだ付けできた <a target="_blank" rel="nofollow noopener" href="https://t.co/Xoyr1HdYq0">pic.twitter.com/Xoyr1HdYq0</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1133687511908175872?ref_src=twsrc%5Etfw">May 29, 2019</a></blockquote> <p>Pro Microを取り付ける。<br /> 今スルーピンヘッダを買ったのでピンヘッダとPro Microははんだ付けしたけれど、ピンヘッダとPCBははんだ付けしていない。</p> <blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">プロマイクロつけ終わった <a target="_blank" rel="nofollow noopener" href="https://t.co/jkfoiJ4zKu">pic.twitter.com/jkfoiJ4zKu</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1133698107063988224?ref_src=twsrc%5Etfw">May 29, 2019</a></blockquote> <p>ここまで来て後はキーキャップとケースつけたら終わり!かと思いきやスペーサーを買い忘れてケースを着けられない。</p> <h3 id="5月30日"><a href="#5%E6%9C%8830%E6%97%A5">5月30日</a></h3> <p>スペーサーを買いに行こうとした。<br /> 財布忘れた。</p> <p>とりあえずキーキャップを着けて作った気になる。</p> <blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">今日は財布を忘れてスペーサーを買えませんでしたが、とりあえずキーキャップつけました。赤買ったんだけど思ってたよりピンク寄り <a target="_blank" rel="nofollow noopener" href="https://t.co/LJk5Od4z4E">pic.twitter.com/LJk5Od4z4E</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1133975065169580032?ref_src=twsrc%5Etfw">May 30, 2019</a></blockquote> <p>そのまま動作確認をする。<br /> どうやらPキーが効かない。</p> <h3 id="5月31日"><a href="#5%E6%9C%8831%E6%97%A5">5月31日</a></h3> <p>Pキーの他に右シフトも効かなかったのではんだ付けした。<br /> スペーサーも買ったけどネジの経を間違えて買ってしまったため入らなかった。</p> <h3 id="6月10日"><a href="#6%E6%9C%8810%E6%97%A5">6月10日</a></h3> <p>注文したスペーサーとネジが届いたのでケースを取り付けました。</p> <h4 id="完成!!!!"><a href="#%E5%AE%8C%E6%88%90%EF%BC%81%EF%BC%81%EF%BC%81%EF%BC%81">完成!!!!</a></h4> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">完成したものがこちらです <a target="_blank" rel="nofollow noopener" href="https://t.co/h0mh9QF42d">pic.twitter.com/h0mh9QF42d</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1138006901734531073?ref_src=twsrc%5Etfw">June 10, 2019</a></blockquote> <p>Pro Microが外れやすいのでティッシュを挟んでいる。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ちなみに、Pro Microとピンヘッダははんだ付けしてあるけどPCBとピンヘッダはしてないのでPro Microがとても外れやすいのでティッシュ挟んで誤魔化してます <a target="_blank" rel="nofollow noopener" href="https://t.co/9475z5h4Pg">pic.twitter.com/9475z5h4Pg</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1138008231630872577?ref_src=twsrc%5Etfw">June 10, 2019</a></blockquote> <p>日を置いたり足りないものがあったりしたせいで、組み立て開始から完成まで50日近くかかりました。<br /> 長かった</p> <h2 id="反省点"><a href="#%E5%8F%8D%E7%9C%81%E7%82%B9">反省点</a></h2> <ul> <li>必要なものは事前にちゃんと確認して揃えましょう</li> <li>買う前にそのパーツで良いのかちゃんと確認しましょう</li> </ul> <h2 id="完成してから"><a href="#%E5%AE%8C%E6%88%90%E3%81%97%E3%81%A6%E3%81%8B%E3%82%89">完成してから</a></h2> <p>しばらくは使いながらキー設定をいじるのを繰り返していました。<br /> キー設定すごい悩みますね。</p> <p>格子配列に慣れていないせいで使いづらく感じることもありましたがだんだん慣れてきました。<br /> 楽しい。</p> <h2 id="今後"><a href="#%E4%BB%8A%E5%BE%8C">今後</a></h2> <p>作ったIrisを無線化しようと考えています。</p> <hr /> <p>この記事は組み立てたIrisで書きました。</p> block tag:crieit.net,2005:PublicArticle/15015 2019-05-23T17:55:31+09:00 2019-05-27T11:36:40+09:00 https://crieit.net/posts/Discord-Splatoon2-bot DiscordからSplatoon2の情報を取得できるbotを作った <h1 id="DiscordからSplatoon2の情報を取得できるbotを作った"><a href="#Discord%E3%81%8B%E3%82%89Splatoon2%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97%E3%81%A7%E3%81%8D%E3%82%8Bbot%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%9F">DiscordからSplatoon2の情報を取得できるbotを作った</a></h1> <h2 id="どんなbot?"><a href="#%E3%81%A9%E3%82%93%E3%81%AAbot%EF%BC%9F">どんなbot?</a></h2> <p>botがいるサーバーで<br /> 「ナワバリ」とコメントすると現在のステージ2つが返ってきます。<br /> 「ガチ」or 「リーグ」とコメントすると現在のステージ2つとルールが返って来ます。<br /> 「サーモンラン」とコメントすると現在のステージと使用可能な武器が返ってきます。</p> <p>他にも機能があるのですが長くなるので気になる方は下記リンク先の説明を読んでください。<br /> <a target="_blank" rel="nofollow noopener" href="https://cube-library.net/works/co-production-works/splatoon2-bot-discord/">イカボット</a></p> <h2 id="なんで作ったの?"><a href="#%E3%81%AA%E3%82%93%E3%81%A7%E4%BD%9C%E3%81%A3%E3%81%9F%E3%81%AE%EF%BC%9F">なんで作ったの?</a></h2> <p>友人との会話の流れで作ることになった。<br /> 他の方が作ったbotが既にあったが対応しているコマンドが覚えにくかったらしい。<br /> - 「ガチ」「リーグ」「ガチマ」「リグマ」「バイト」とかいろんな表現で情報を取得したい<br /> - 他にも情報を取得したい</p> <p>とかそんな理由で開発がスタートした。</p> <h2 id="開発・実行環境"><a href="#%E9%96%8B%E7%99%BA%E3%83%BB%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83">開発・実行環境</a></h2> <h3 id="言語とライブラリ"><a href="#%E8%A8%80%E8%AA%9E%E3%81%A8%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA">言語とライブラリ</a></h3> <p>PythonからDiscordにアクセスできる<a target="_blank" rel="nofollow noopener" href="https://github.com/Rapptz/discord.py">discord.py</a>というライブラリが既に公開されていたのでそれを使用した。<br /> 開発当時はPython3.7に対応していなかったのでPythonのバージョンは3.6で開発した。</p> <h3 id="Splatoon2の情報の取得元"><a href="#Splatoon2%E3%81%AE%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%96%E5%BE%97%E5%85%83">Splatoon2の情報の取得元</a></h3> <p>下記サイトでSplatoon2のステージ情報を取得できるAPIを公開している方がいたため、ありがたく使わせていただきました。<br /> <a target="_blank" rel="nofollow noopener" href="https://spla2.yuu26.com/">Spla2 API</a></p> <p>大量のアクセスを行わないように + 高速化のためスケジュール更新があるまではキャッシュしたデータをもとにステージ情報などを返すようにしている。</p> <h3 id="実行環境"><a href="#%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83">実行環境</a></h3> <p>GCPで仮想サーバーを立ててSupervisorでデーモン化した。</p> <p>参考にした記事↓<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/shiraco/items/70c5d48a1b4f43fb4aa7">SupervisorでPythonのWebアプリをデーモン化する</a></p> <h2 id="開発中の苦労"><a href="#%E9%96%8B%E7%99%BA%E4%B8%AD%E3%81%AE%E8%8B%A6%E5%8A%B4">開発中の苦労</a></h2> <p>Pythonをまともに書いたことがなかったので慣れるまでは開発スピードが遅かった。<br /> 特に普段は型ありの言語しか書かないので、型が違うエラーが実行時にしかわからないのが苦労した。</p> <h2 id="今後"><a href="#%E4%BB%8A%E5%BE%8C">今後</a></h2> <ul> <li>機能追加(要望があれば)</li> <li>Python 3.7対応</li> </ul> <h2 id="リンク"><a href="#%E3%83%AA%E3%83%B3%E3%82%AF">リンク</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://discordapp.com/api/oauth2/authorize?client_id=547404858135805992&permissions=2048&scope=bot">botをサーバーに登録するためのリンク</a></p> block tag:crieit.net,2005:PublicArticle/14947 2019-04-24T13:59:41+09:00 2019-04-24T14:06:43+09:00 https://crieit.net/posts/Iris Irisビルドログ(途中) <h1 id="Irisビルドログ"><a href="#Iris%E3%83%93%E3%83%AB%E3%83%89%E3%83%AD%E3%82%B0">Irisビルドログ</a></h1> <p>初めての自作キーボードのビルドログ</p> <h2 id="Irisって?"><a href="#Iris%E3%81%A3%E3%81%A6%3F">Irisって?</a></h2> <p>左右分離型のキーボードで、列によってキーが若干ずれてる。<br /> ↓PCBを売ってるサイトの画像で雰囲気はわかる<br /> <a target="_blank" rel="nofollow noopener" href="https://keeb.io/collections/frontpage/products/iris-keyboard-split-ergonomic-keyboard?variant=8034004860958">https://keeb.io/collections/frontpage/products/iris-keyboard-split-ergonomic-keyboard?variant=8034004860958</a></p> <h2 id="なぜIrisを選んだか"><a href="#%E3%81%AA%E3%81%9CIris%E3%82%92%E9%81%B8%E3%82%93%E3%81%A0%E3%81%8B">なぜIrisを選んだか</a></h2> <p>最低限<br /> - 左右分離型<br /> - キー配置が格子配列かそれに近い</p> <p>という条件で探していたところ、通常の格子配列よりも指が楽そうなIrisが目に止まった。<br /> Corneも候補にあったが悩んでいるときに売り切れだったので諦めた。</p> <h2 id="組み立て過程"><a href="#%E7%B5%84%E3%81%BF%E7%AB%8B%E3%81%A6%E9%81%8E%E7%A8%8B">組み立て過程</a></h2> <p>組み立て前</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今日はついに自分の自作キーボードを作り始めるよ!</p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120618834505768960?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>キーボードケースをベニヤとアクリルの2種類切り出してもらっていたので直前まで悩んでいた。<br /> 最終的にはアクリルに決めた。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">フレームをベニヤとアクリルで悩んでる <a target="_blank" rel="nofollow noopener" href="https://t.co/NYwDtYWMkY">pic.twitter.com/NYwDtYWMkY</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120631012998795264?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>ダイオードを折り曲げてPCBに挿していく。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ダイオード刺し終わった <a target="_blank" rel="nofollow noopener" href="https://t.co/135vXzbmea">pic.twitter.com/135vXzbmea</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120640899313098752?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>PCBにダイオードをはんだ付けする。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ダイオードのはんだ付け終わり!汚いww <a target="_blank" rel="nofollow noopener" href="https://t.co/CbgvzI9JE9">pic.twitter.com/CbgvzI9JE9</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120646856915075073?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>リセットスイッチとTRRSケーブル挿す部分を取り付ける。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ケーブルつなぐやつ(名前忘れた)とリセットスイッチの取り付け完了! <a target="_blank" rel="nofollow noopener" href="https://t.co/COFCx7q3Ot">pic.twitter.com/COFCx7q3Ot</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120648971771240449?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>LEDをつけるなら必要になる抵抗をはんだ付けする。<br /> 実はまだLEDをつけるかどうかを決めていない。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">オプションの抵抗 <a target="_blank" rel="nofollow noopener" href="https://t.co/xTPwL0WWTN">pic.twitter.com/xTPwL0WWTN</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120650167932166144?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>ダイオードの余った線をニッパーで切っていく。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ダイオードの余った部分切った <a target="_blank" rel="nofollow noopener" href="https://t.co/72GdtiUacu">pic.twitter.com/72GdtiUacu</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120654549616750593?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <p>ケースとスイッチを取り付ける。裏側はまだ取り付けていない。<br /> 軸は静音赤軸(ピンク軸)。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ケースとスイッチつけた! <a target="_blank" rel="nofollow noopener" href="https://t.co/eVBIRC9bJC">pic.twitter.com/eVBIRC9bJC</a></p>— block (@block_cube_lib) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/block_cube_lib/status/1120663362247909377?ref_src=twsrc%5Etfw">2019年4月23日</a></blockquote> <hr /> <p>初日の作業はここまで</p> <h2 id="ここまでの感想とか"><a href="#%E3%81%93%E3%81%93%E3%81%BE%E3%81%A7%E3%81%AE%E6%84%9F%E6%83%B3%E3%81%A8%E3%81%8B">ここまでの感想とか</a></h2> <ul> <li>はんだ付け慣れると楽しい</li> <li>はんだごての温度は高めの方がやりやすい</li> <li>PCBの余った部分をニッパーで切るのは楽しくない</li> <li>Twitterで進捗を上げると色んな人が反応してくれて楽しい</li> <li>換気はちゃんとしないと喉とか鼻とかしんどい</li> <li>質問できる人が近くにいるととても助かる</li> </ul> block tag:crieit.net,2005:PublicArticle/14889 2019-03-28T16:09:17+09:00 2019-04-03T00:17:03+09:00 https://crieit.net/posts/T-From-U-impl-From-Wrapper-U-for-Wrapper-T T: From<U>のときimpl From<Wrapper<U>> for Wrapper<T>ができない <h1 id="T: From&lt;U&gt;のときimpl From&lt;Wrapper&lt;U&gt;&gt; for Wrapper&lt;T&gt;ができない"><a href="#T%3A+From%26lt%3BU%26gt%3B%E3%81%AE%E3%81%A8%E3%81%8Dimpl+From%26lt%3BWrapper%26lt%3BU%26gt%3B%26gt%3B+for+Wrapper%26lt%3BT%26gt%3B%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">T: From<U>のときimpl From<Wrapper<U>> for Wrapper<T>ができない</a></h1> <p>これができない。</p> <pre><code class="rust">struct Wrapper<T>(T); impl<T, U> From<Wrapper<U>> for Wrapper<T> where T: From<U>, { fn from(p: Wrapper<U>) -> Wrapper<T> { Wrapper(p.0.into()) } } fn main() { let a = Wrapper::<i32>(42); let _: Wrapper<f32> = a.into(); } </code></pre> <h2 id="エラー内容"><a href="#%E3%82%A8%E3%83%A9%E3%83%BC%E5%86%85%E5%AE%B9">エラー内容</a></h2> <pre><code> Compiling playground v0.0.1 (/playground) error[E0119]: conflicting implementations of trait `std::convert::From<Wrapper<_>>` for type `Wrapper<_>`: --> src/main.rs:3:1 | 3 | / impl<T, U> From<Wrapper<U>> for Wrapper<T> 4 | | where 5 | | T: From<U>, 6 | | { ... | 9 | | } 10 | | } | |_^ | = note: conflicting implementation in crate `core`: - impl<T> std::convert::From<T> for T; error: aborting due to previous error For more information about this error, try `rustc --explain E0119`. error: Could not compile `playground`. To learn more, run the command again with --verbose. </code></pre> <hr /> <p><a target="_blank" rel="nofollow noopener" href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c2684882a6c547090142be06ca64f8ce">実行できるコード</a></p> <p>おそらく同じ型同士のFrom(<code>impl From<T> for T</code>)と衝突している。</p> block tag:crieit.net,2005:PublicArticle/14698 2018-12-27T18:27:22+09:00 2018-12-27T18:27:22+09:00 https://crieit.net/posts/T-T ユーザー定義型 * Tは実装できるがT * ユーザー定義型は実装できない <h1 id="ユーザー定義型 * Tは実装できるがT * ユーザー定義型は実装できない"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%AE%9A%E7%BE%A9%E5%9E%8B+%2A+T%E3%81%AF%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%8CT+%2A+%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%AE%9A%E7%BE%A9%E5%9E%8B%E3%81%AF%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">ユーザー定義型 * Tは実装できるがT * ユーザー定義型は実装できない</a></h1> <h2 id="例"><a href="#%E4%BE%8B">例</a></h2> <p>任意の型の要素を持つ<code>Vector1<T></code>を定義して<code>T * T</code>が可能であれば<code>Vector1<T> * T</code>と<code>T * Vector1<T></code>ができるようにしたいとします。</p> <pre><code class="rust">struct Vector1<T> { x: T } // T * Tが可能であれば // Vector1<T> * Tと // T * Vector1<T>を可能にしたい </code></pre> <p>しかし<code>Vector1<T> * T</code>は実装できるのですが<code>T * Vector1<T></code>は実装できません。</p> <h2 id="とりあえず実装してみる"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">とりあえず実装してみる</a></h2> <pre><code class="rust">use std::ops; struct Vector1<T> { x: T, } impl<T> ops::Mul<T> for Vector1<T> where T: ops::Mul<T, Output = T>, { type Output = Vector1<T>; fn mul(self, rhs: T) -> Vector1<T> { Vector1 { x: self.x * rhs } } } impl<T> ops::Mul<Vector1<T>> for T where T: ops::Mul<T, Output = T>, { type Output = Vector1<T>; fn mul(self, rhs: Vector1<T>) -> Vector1<T> { Vector1 { x: self * rhs.x } } } fn main() {} </code></pre> <p>エラーが出ました。</p> <pre><code> | 18 | / impl<T> ops::Mul<Vector1<T>> for T 19 | | where 20 | | T: ops::Mul<T, Output = T>, 21 | | { ... | 26 | | } 27 | | } | |_^ type parameter `T` must be used as the type parameter for some local type | = note: only traits defined in the current crate can be implemented for a type parameter </code></pre> <hr /> <p>Rust Playgroundでエラーを確認できます。<br /> <a target="_blank" rel="nofollow noopener" href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7d83e5369d7c227e28e27f408d7d45b7">https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7d83e5369d7c227e28e27f408d7d45b7</a></p> block