【プログラミング】アドバイス2:早期リターン

このコミットが含まれているのは:
守矢諏訪子 2023-12-25 19:11:02 +09:00
コミット 4152629864
8個のファイルの変更268行の追加42行の削除

ファイルの表示

@ -3,13 +3,106 @@
<id>gemini://technicalsuwako.moe</id>
<title>テクニカル諏訪子</title>
<updated>2023-12-12T00:00:00Z</updated>
<updated>2023-12-21T00:00:00Z</updated>
<author><name>テクニカル諏訪子</name></author>
<link href="gemini://technicalsuwako.moe" rel="alternate"></link>
<entry>
<id>blog/programming-early-return.gmi</id>
<author><name>凛</name></author>
<title type="html">【プログラミング】アドバイス2:早期リターン</title>
<published>2023-12-21T00:00:00Z</published>
<category term="jp"></category>
<category term="blog"></category>
<category term="システム開発"></category>
<category term="c言語"></category>
<category term="プログラミング"></category>
<link href="gemini://technicalsuwako.moe/blog/programming-early-return.gmi" rel="alternate"></link>
<content type="html">
&lt;p&gt;&lt;a href=&#34;/blog/programming-pyramid-of-doom/&#34;&gt;前回は運命のピラミッドを避ける事について話しました。&lt;/a&gt;&lt;br /&gt;
運命のピラミッドを避けるる際、早期リターンをよく使用します。&lt;/p&gt;
&lt;h2 id=&#34;heading&#34;&gt;早期リターンとは?&lt;/h2&gt;
&lt;p&gt;早期リターンは、特定の条件が真(true)の場合に、関数の実行を直ぐに終了させる事です。&lt;br /&gt;
例えば、エラーが発生した場合、関数の最後まで実行する意味はありませんので、早期リターンを使う方が良いでしょう。&lt;/p&gt;
&lt;p&gt;C言語の例(早期リターンを使わない場合)&lt;/p&gt;
&lt;pre&gt;&lt;code lang=&#34;&#34;&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#00a000&#34;&gt;get_token&lt;/span&gt;() {
&lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; malloc(&lt;span style=&#34;color:#666&#34;&gt;64&lt;/span&gt;);
json_object &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; curl_con(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;auth/login&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;, data, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (res &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;NULL&lt;/span&gt;) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;エラー:ログインに失敗。&amp;#34;&lt;/span&gt;);
token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;;
}
json_object &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;data_obj, &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;token_obj;
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#666&#34;&gt;!&lt;/span&gt;json_object_object_get_ex(res, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;data_obj)) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;JSONで&amp;#39;data&amp;#39;を見つけられませんでした。&amp;#34;&lt;/span&gt;);
token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;;
}
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#666&#34;&gt;!&lt;/span&gt;json_object_object_get_ex(data_obj, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;token&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;token_obj)) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;JSONの&amp;#39;data&amp;#39;鍵で、&amp;#39;token&amp;#39;を見つけられませんでした。&amp;#34;&lt;/span&gt;);
token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;;
}
token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; json_object_get_string(token_obj);
json_object_put(res);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; token;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上記の問題は、3つの異なるエラーチェックがあるにも関わらず、エラーが発生しても最後まで処理を続ける事です。&lt;br /&gt;
それは非効率的です。&lt;br /&gt;
さらに、上記の例ではメモリリークが発生する可能性がある為、この方法はお勧め出来ません。&lt;br /&gt;
そこで、早期リターンを使って問題を解決しましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code lang=&#34;&#34;&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#00a000&#34;&gt;get_token&lt;/span&gt;() {
&lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; malloc(&lt;span style=&#34;color:#666&#34;&gt;64&lt;/span&gt;);
json_object &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; curl_con(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;auth/login&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;, data, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (res &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;NULL&lt;/span&gt;) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;エラー:ログインに失敗。&amp;#34;&lt;/span&gt;);
free(token); &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// メモリ割当しましたが、エラーが発生したから、開放して下さい
&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;NULL&lt;/span&gt;; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// エラーが発生したから、終了しよう
&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt; }
json_object &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;data_obj, &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;token_obj;
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#666&#34;&gt;!&lt;/span&gt;json_object_object_get_ex(res, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;data_obj)) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;JSONで&amp;#39;data&amp;#39;を見つけられませんでした。&amp;#34;&lt;/span&gt;);
json_object_put(res); &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// エラーが発生したから、JSONオブジェクトを開放する
&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt; free(token);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;NULL&lt;/span&gt;;
}
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#666&#34;&gt;!&lt;/span&gt;json_object_object_get_ex(data_obj, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;token&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;token_obj)) {
printf(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;JSONの&amp;#39;data&amp;#39;鍵で、&amp;#39;token&amp;#39;を見つけられませんでした。&amp;#34;&lt;/span&gt;);
json_object_put(res);
free(token);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;NULL&lt;/span&gt;;
}
token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; json_object_get_string(token_obj);
json_object_put(res);
&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; token;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;結果は同じですが、処理が少なくなる為、効率が向上します。&lt;/p&gt;
&lt;p&gt;以上&lt;/p&gt;
</content>
</entry>
<entry>
<id>blog/byobu-52.gmi</id>
<author><name>凛</name></author>
@ -488,40 +581,5 @@ zroot/usr/src 29G 96K 29G 0% /usr/src
</content>
</entry>
<entry>
<id>blog/sp-111.gmi</id>
<author><name>凛</name></author>
<title type="html">【】sp 1.1.1登場</title>
<published>2023-12-01T13:00:00Z</published>
<category term="jp"></category>
<category term="blog"></category>
<category term="ウエブ開発"></category>
<category term=""></category>
<category term="sp"></category>
<link href="gemini://technicalsuwako.moe/blog/sp-111.gmi" rel="alternate"></link>
<content type="html">
&lt;h2 id=&#34;sp&#34;&gt;spって何?&lt;/h2&gt;
&lt;p&gt;spはシンプルなパスワードマネージャです。&lt;/p&gt;
&lt;h2 id=&#34;heading&#34;&gt;変更&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;make install-zsh部分を修正&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;heading-1&#34;&gt;ソースコード&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://gitler.moe/suwako/sp&#34;&gt;Gitler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;以上&lt;/p&gt;
</content>
</entry>
</feed>

ファイルの表示

@ -2,6 +2,7 @@
# 記事一覧
=> /blog/programming-early-return.gmi 2023年12月21日 【プログラミング】アドバイス2:早期リターン
=> /blog/byobu-52.gmi 2023年12月12日 【】byobu 5.2登場
=> /blog/digital-autonomy-076video-hosting.gmi 2023年12月11日 【デジタル自主】076動画ホスティングの解決策
=> /blog/programming-pyramid-of-doom.gmi 2023年12月05日 【プログラミング】アドバイス1:運命のピラミッドを回避

82
gemini/blog/programming-early-return.gmi ノーマルファイル
ファイルの表示

@ -0,0 +1,82 @@
=> /blog.gmi ブログ一覧へ
# 【プログラミング】アドバイス2:早期リターン
投稿日2023-12-21
=> /blog/programming-pyramid-of-doom.gmi 前回は運命のピラミッドを避ける事について話しました。
運命のピラミッドを避けるる際、早期リターンをよく使用します。
## 早期リターンとは?
早期リターンは、特定の条件が真(true)の場合に、関数の実行を直ぐに終了させる事です。
例えば、エラーが発生した場合、関数の最後まで実行する意味はありませんので、早期リターンを使う方が良いでしょう。
C言語の例(早期リターンを使わない場合)
```c
const char *get_token() {
char *token = malloc(64);
json_object *res = curl_con("auth/login", "POST", data, "");
if (res == NULL) {
printf("エラー:ログインに失敗。");
token = "";
}
json_object *data_obj, *token_obj;
if (!json_object_object_get_ex(res, "data", &data_obj)) {
printf("JSONで'data'を見つけられませんでした。");
token = "";
}
if (!json_object_object_get_ex(data_obj, "token", &token_obj)) {
printf("JSONの'data'鍵で、'token'を見つけられませんでした。");
token = "";
}
token = json_object_get_string(token_obj);
json_object_put(res);
return token;
}
```
上記の問題は、3つの異なるエラーチェックがあるにも関わらず、エラーが発生しても最後まで処理を続ける事です。
それは非効率的です。
さらに、上記の例ではメモリリークが発生する可能性がある為、この方法はお勧め出来ません。
そこで、早期リターンを使って問題を解決しましょう。
```c
const char *get_token() {
char *token = malloc(64);
json_object *res = curl_con("auth/login", "POST", data, "");
if (res == NULL) {
printf("エラー:ログインに失敗。");
free(token); // メモリ割当しましたが、エラーが発生したから、開放して下さい
return NULL; // エラーが発生したから、終了しよう
}
json_object *data_obj, *token_obj;
if (!json_object_object_get_ex(res, "data", &data_obj)) {
printf("JSONで'data'を見つけられませんでした。");
json_object_put(res); // エラーが発生したから、JSONオブジェクトを開放する
free(token);
return NULL;
}
if (!json_object_object_get_ex(data_obj, "token", &token_obj)) {
printf("JSONの'data'鍵で、'token'を見つけられませんでした。");
json_object_put(res);
free(token);
return NULL;
}
token = json_object_get_string(token_obj);
json_object_put(res);
return token;
}
```
結果は同じですが、処理が少なくなる為、効率が向上します。
以上

ファイルの表示

@ -18,9 +18,11 @@
=> https://video.076.moe/a/suwako PeerTubeで登録
## ミラー(HTTP)
=> https://technicalsuwako.moe/ 一般ネット 1
=> https://technicalsuwako.moe/ 一般ネット 1 (GUI)
=> https://cli.technicalsuwako.moe/ 一般ネット 1 (CLI)
=> https://tilde.club/~technicalsuwako/ 一般ネット 2
=> http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/ Tor
=> http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/ Tor (GUI)
=> http://cli.6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/ Tor (CLI)
=> http://technicalsuwako.i2p/ I2P
=> http://technicalsuwako.i2p/?i2paddresshelper=ubsJs74cyvIxM5CAnadTpNP~8nL3FylU6CC9EzXlaLQVbUuzwzDWSrvTwTEiS1~GTlPaoMxlHe7vCHk0Mn4dnTg-wVZts721rHhu8w4cb0RPVneU5jmcXItsPMyg4oXLVLhv~qe4CEJDFHv6kumFZHUVw~bzorCvwUuISSBM1CqbmZ~SWz0MOHHQBBkIzUHncl~oTGHYJ2AGS0-RLmTSNQIv9Eam1X7EWOmi4VBTpGf-n39QjltWL6SKr9um49OgsYochG6pC8l0kneaIjpDrGUr1jJ6MrwTZxxMWeykuxZv1Vwta74tITjijVyBwKUmlHtUHnnH7IukvEGq5S-6YXUZO~nu5PC~ycNJ35mQUJDmiGAikUUY-vUHk0FvDP30XEQnubsOKEyKBXnd7hSDw8IAO~eAaE8gI21zCMW58Qey11WsxCzM1fAmIN9Y0af~eKkmSTbn14Ma0CGl9M8vt1h5k0i-rKt-V76DR5eyYQ6JBwT7UqB6qiD90OMaaQ6rBQAEAAcAAA== I2P アドレスヘルパー
=> http://73pxqisewxlcjmbjyxnorg5ngq54ii6nmoxt3knaod6ggry7dq4a.b32.i2p/ I2P B32

ファイルの表示

@ -3,6 +3,7 @@
# avatar = gemini://076.moe/static/suwako.jpg
# description = テクニカル諏訪子様のtwtxtフィード
# link = ホームページ gemini://technicalsuwako.moe
2023-12-21T00:00:00Z09:00 【プログラミング】アドバイス2:早期リターン - gemini://technicalsuwako.moe/blog/blog/programming-early-return.gmi
2023-12-12T00:00:00Z09:00 【】byobu 5.2登場 - gemini://technicalsuwako.moe/blog/blog/byobu-52.gmi
2023-12-11T00:00:00Z09:00 【デジタル自主】076動画ホスティングの解決策 - gemini://technicalsuwako.moe/blog/blog/digital-autonomy-076video-hosting.gmi
2023-12-05T00:00:00Z09:00 【プログラミング】アドバイス1:運命のピラミッドを回避 - gemini://technicalsuwako.moe/blog/blog/programming-pyramid-of-doom.gmi

ファイルの表示

@ -44,9 +44,9 @@
</div>
<div class="header-links">
ミラー(HTTP)
<a href="https://technicalsuwako.moe/">一般ネット</a> |
<a href="https://technicalsuwako.moe/">一般ネット</a> (<a href="https://cli.technicalsuwako.moe/">CLI</a>) |
<a href="https://tilde.club/~technicalsuwako/">Tilde</a> |
<a href="http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/">Tor</a> |
<a href="http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/">Tor</a> (<a href="http://cli.6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/">CLI</a>) |
<a href="http://technicalsuwako.i2p/">I2P</a> (<a href="http://technicalsuwako.i2p/?i2paddresshelper=ubsJs74cyvIxM5CAnadTpNP~8nL3FylU6CC9EzXlaLQVbUuzwzDWSrvTwTEiS1~GTlPaoMxlHe7vCHk0Mn4dnTg-wVZts721rHhu8w4cb0RPVneU5jmcXItsPMyg4oXLVLhv~qe4CEJDFHv6kumFZHUVw~bzorCvwUuISSBM1CqbmZ~SWz0MOHHQBBkIzUHncl~oTGHYJ2AGS0-RLmTSNQIv9Eam1X7EWOmi4VBTpGf-n39QjltWL6SKr9um49OgsYochG6pC8l0kneaIjpDrGUr1jJ6MrwTZxxMWeykuxZv1Vwta74tITjijVyBwKUmlHtUHnnH7IukvEGq5S-6YXUZO~nu5PC~ycNJ35mQUJDmiGAikUUY-vUHk0FvDP30XEQnubsOKEyKBXnd7hSDw8IAO~eAaE8gI21zCMW58Qey11WsxCzM1fAmIN9Y0af~eKkmSTbn14Ma0CGl9M8vt1h5k0i-rKt-V76DR5eyYQ6JBwT7UqB6qiD90OMaaQ6rBQAEAAcAAA==">AH</a>, <a href="http://73pxqisewxlcjmbjyxnorg5ngq54ii6nmoxt3knaod6ggry7dq4a.b32.i2p/">B32</a>)
</div>
<div class="header-links">

ファイルの表示

@ -91,9 +91,9 @@
</div>
<div class="header-links">
ミラー(HTTP)
<a href="https://technicalsuwako.moe/"><img class="icon" src="/static/clearnet.png" alt="" />一般ネット</a> |
<a href="https://technicalsuwako.moe/"><img class="icon" src="/static/clearnet.png" alt="" />一般ネット</a> (<a href="https://cli.technicalsuwako.moe/">CLI</a>) |
<a href="https://tilde.club/~technicalsuwako/"><img class="icon" src="/static/tilde.png" alt="" />Tilde</a> |
<a href="http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/"><img class="icon" src="/static/tor.png" alt="" />Tor</a> |
<a href="http://6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/"><img class="icon" src="/static/tor.png" alt="" />Tor</a> (<a href="http://cli.6qiatzlijtqo6giwvuhex5zgg3czzwrq5g6yick3stnn4xekw26zf7qd.onion/">CLI</a>) |
<a href="http://technicalsuwako.i2p/"><img class="icon" src="/static/i2p.png" alt="" />I2P</a> (<a href="http://technicalsuwako.i2p/?i2paddresshelper=ubsJs74cyvIxM5CAnadTpNP~8nL3FylU6CC9EzXlaLQVbUuzwzDWSrvTwTEiS1~GTlPaoMxlHe7vCHk0Mn4dnTg-wVZts721rHhu8w4cb0RPVneU5jmcXItsPMyg4oXLVLhv~qe4CEJDFHv6kumFZHUVw~bzorCvwUuISSBM1CqbmZ~SWz0MOHHQBBkIzUHncl~oTGHYJ2AGS0-RLmTSNQIv9Eam1X7EWOmi4VBTpGf-n39QjltWL6SKr9um49OgsYochG6pC8l0kneaIjpDrGUr1jJ6MrwTZxxMWeykuxZv1Vwta74tITjijVyBwKUmlHtUHnnH7IukvEGq5S-6YXUZO~nu5PC~ycNJ35mQUJDmiGAikUUY-vUHk0FvDP30XEQnubsOKEyKBXnd7hSDw8IAO~eAaE8gI21zCMW58Qey11WsxCzM1fAmIN9Y0af~eKkmSTbn14Ma0CGl9M8vt1h5k0i-rKt-V76DR5eyYQ6JBwT7UqB6qiD90OMaaQ6rBQAEAAcAAA==">AH</a>, <a href="http://73pxqisewxlcjmbjyxnorg5ngq54ii6nmoxt3knaod6ggry7dq4a.b32.i2p/">B32</a>)
</div>
<div class="header-links">

82
src/blog/programming-early-return/index.md ノーマルファイル
ファイルの表示

@ -0,0 +1,82 @@
title: 【プログラミング】アドバイス2:早期リターン
author: 凛
date: 2023-12-21
tags: jp,blog,システム開発,c言語,プログラミング
----
[前回は運命のピラミッドを避ける事について話しました。](/blog/programming-pyramid-of-doom/)\
運命のピラミッドを避けるる際、早期リターンをよく使用します。
## 早期リターンとは?
早期リターンは、特定の条件が真(true)の場合に、関数の実行を直ぐに終了させる事です。\
例えば、エラーが発生した場合、関数の最後まで実行する意味はありませんので、早期リターンを使う方が良いでしょう。
C言語の例(早期リターンを使わない場合)
```c
const char *get_token() {
char *token = malloc(64);
json_object *res = curl_con("auth/login", "POST", data, "");
if (res == NULL) {
printf("エラー:ログインに失敗。");
token = "";
}
json_object *data_obj, *token_obj;
if (!json_object_object_get_ex(res, "data", &data_obj)) {
printf("JSONで'data'を見つけられませんでした。");
token = "";
}
if (!json_object_object_get_ex(data_obj, "token", &token_obj)) {
printf("JSONの'data'鍵で、'token'を見つけられませんでした。");
token = "";
}
token = json_object_get_string(token_obj);
json_object_put(res);
return token;
}
```
上記の問題は、3つの異なるエラーチェックがあるにも関わらず、エラーが発生しても最後まで処理を続ける事です。\
それは非効率的です。\
さらに、上記の例ではメモリリークが発生する可能性がある為、この方法はお勧め出来ません。\
そこで、早期リターンを使って問題を解決しましょう。
```c
const char *get_token() {
char *token = malloc(64);
json_object *res = curl_con("auth/login", "POST", data, "");
if (res == NULL) {
printf("エラー:ログインに失敗。");
free(token); // メモリ割当しましたが、エラーが発生したから、開放して下さい
return NULL; // エラーが発生したから、終了しよう
}
json_object *data_obj, *token_obj;
if (!json_object_object_get_ex(res, "data", &data_obj)) {
printf("JSONで'data'を見つけられませんでした。");
json_object_put(res); // エラーが発生したから、JSONオブジェクトを開放する
free(token);
return NULL;
}
if (!json_object_object_get_ex(data_obj, "token", &token_obj)) {
printf("JSONの'data'鍵で、'token'を見つけられませんでした。");
json_object_put(res);
free(token);
return NULL;
}
token = json_object_get_string(token_obj);
json_object_put(res);
return token;
}
```
結果は同じですが、処理が少なくなる為、効率が向上します。
以上