質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

2回答

2707閲覧

(主にGo言語の)引数の順番について

damalnylpo

総合スコア53

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

1グッド

0クリップ

投稿2016/07/22 13:47

編集2016/07/22 13:52

###質問したいこと
引数の順番を決める時には何か比較的浸透しているルールがあるのでしょうか?
言語ごとに同じ関数でも異なることがあるので決まった答えはないと思いますが
golangにそういったものがあれば教えていただきたいです。

###引数の順番
引数は当然複数設定することがしばしばありますが
その際、どういった値を最初に持ってくるだとかという話をあまり見ることがありません。

go

1func Join([]string,string)string

上記のようにGo言語では文字列を連結するJoin関数は配列が先に来ますが

perl

1sub join(string,[]string)

上記のようにPerlでは配列が後に置かれます。
Perlは配列の扱いが可変長引数と近く、
配列が最後に来るのは言語的な部分があるので
golangの順番が一般的にも妥当だとかもしれませんが
どちらにせよ何を基準に順番を決めているのでしょうか?
命名規則などはしばしば議論に上がりますがこの手の話は今一つ主流というか、
一般的にどう考えられているのかがつかめません。

もちろんこれは一般的な基準があるわけではないので
多少好みの問題でどちらが正しいというのはないと思いますが
言語のライブラリとしてはある程度統一しているべきだと思いますし、
そういったルールが丁寧なgolangなら尚更何か理由があると思います。
しかしEffective Goなどを見ていてもそれらしい記述は見当たりません。(見落としてるかもしれません)

一般的に、もしくはgolangにおいて、
もしそういったものがあったりするのであれば教えていただきたいです。
他の言語においてもその基準のようなものがあるのであれば参考に教えていただけると助かります。

###ありそうな?決め方

  1. オプションは最後

少なくともオプションに近い、あまり意識してつける必要のないものに関しては
最後に置かれるのはほとんどの言語で共通だと思います。
ただオプションだけとは限らないのでこれだけでは厳しいです。
2. オリジナルは最初?
パースをするときなど、戻り値の素材のような引数は最初が良いと思いますが
perlは逆なようです。
3. 英語の文法に合わせる
Joinであれば配列Aを文字列Bで結合するといった内容です。
golangでいえば

go

1//Join concatenates the elements of a to create a single string. The separator string sep is placed between elements in the resulting string." 2func Join(a []string,sep string)string

個人的にこれが無難な気はしますが
並びが変わるよう多少文章の構成を変えることもできるので今一つ釈然としません

###引数の役割
役割で順番を決めるなら
出力、入力、オプションとかでしょうか
しかしこれだけではいくつか被ることも十分あるのでなんともいえません。

golang以外や
個人的な基準でも良いのでいろいろ教えていただけると助かります

ikuwow👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Go言語以外でも良い、ということですので、言語を限定しないで書いてみます。

言語の制約によるもの

joinという関数についていうと、
可変長引数に対して使うことを想定している言語では、
可変長引数は最後にしか置けない場合があり、
その場合はjoin(delim, *args)にせざるを得ません。(delim=区切り文字、*args=可変長引数)
オーバーロードでコレクションを取るメソッドの場合も、
これに合わせてjoin(delim, coll)delim=区切り文字、coll=コレクション)になります。

オーバーロードメソッド、デフォルトパラメーターに合わせる

intelfikeさんが書かれていることと、前項の「言語の制約」に関係しますが、
省略できるパラメーターがある場合は優先度が下がります。

慣例に合わせる

言語によって、この場合はこの順序、みたいなのが慣例としてある程度決まっています。
標準ライブラリーを探すと、ある程度その傾向がつかめるのではないかと思います。

標準ライブラリーに含まれる類似の処理に近いものを採用したほうが、
それらのライブラリーを使い慣れている人たちにとっては受け入れやすいでしょう。

関連度

その処理にとって関連性の高い順に並べます。


...

今はこれくらいしか思いつきませんでした。
何か具体的な例があればもう少し思いつくかも知れません。

投稿2016/07/22 15:07

argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

damalnylpo

2016/07/22 22:56 編集

回答ありがとうございます! 自分のライブラリを作る場合は確かに慣例に合わせたほうがよさそうですね。 ただgoではWriter(出力先として扱えるインタフェース)は最初にきますが それを出力が最初に来ると勘違いしてしまうと json.Unmarshal(json文字列 []byte,ポインタ渡しでの受け取り用引数 interface{})error のような形ではinterface{}を出力先と早とちりして最初においてしまいそうです。 関連度は確かに大きな基準かもしれませんね。 json.Unmarshalでいうとjsonそのものの方が関連度は高そうなので筋が通りそうです。
guest

0

ベストアンサー

javaとgoを主に勉強していますが、左の要素程必ず値を入力するという考え方が多いと思います。
とくにjavaでは、変数名を変えずに引数の個数を変えて宣言(オーバーロード)できるので、書かないことがある、融通の利く値を後に回すことが多いです。

java
String#indexOf("A");//文字列を探して位置を返す。
String#indexOf("A", 3);//文字列を探して位置を返す。要素番号3以降から検索開始
のような感じです。

golangにおけるjoinも、join(array, "")のように何も書かずにくっつけることがあると思います。
golangはオーバーロードのようなことはできないみたいですが、このような表記が多いのでそれに合わせているのだと思います。

投稿2016/07/22 14:13

intelf___

総合スコア868

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

damalnylpo

2016/07/22 22:49

回答ありがとうございます! なるほど、言われてみればJoinの結合文字もオプションに近いですね。 ですがオプションでないものが複数ある関数 例えばjson.Unmarshal([]byte,interface{})errorは 第一、第二引数ともに必要だとおもいます。 jsonのフォーマットチェックだけを望むにしてもそれに対応する構造体を入れる必要があるので ほぼ同等の必要性を持っていると思いますが この場合何を基準にしているのでしょう? Interfaceによる参照渡しでの結果受け取り引数は golangでは最後にきますがその理由が気になります。
intelf___

2016/07/23 01:29

windowsでのC言語のuser32.dll関数も、値を受け取るためのポインタは最後に来るみたいですね。 例えばcreateWindowEx()が、引数が12個ある中で値を受け取るポインタは最後に来ています。 https://msdn.microsoft.com/ja-jp/library/cc410714.aspx データベース的な考えからかclassという分類が先に来ています。 データベースでもキーとなるIDが先頭に来ていることが多いです。その直後に名前が来ているのもそれっぽいです。 また、座標関係は位置(横、縦)、大きさ(横、縦)と並んでいて、一般的な座標の表記法を基準にしています。 座標情報は1や2ずれたところでほとんど影響しないのに対して、名前などの識別子は間違えたら大変です。なので、どちらかといえば重要度が高いとしてそちらが優先になったんでしょう。 座標より後の値はNULLを渡しても問題がないものばかりです。 C言語として話してきましたが、go-winapiなどのパッケージをgetすればgolangそのまま使用できるので無関係とは言い切れません。 これを見るに、重要度で大まかに、慣例で細かく順番を決めているように見えますね。 そして最後に値を受け取るためのポインタ、可変長引数、といった感じでしょうか。 完全に引数の長さで選びました。 あくまで一例なので参考までに。
damalnylpo

2016/07/23 10:46

なるほど・・・ 確かに固有の識別子のようなものは最初あたりにあることが多いですね、 プロパティのようなものが中間で オプションが最後という感じでしょうか・・・ createWindowExで拡張ウィンドウスタイルというのが第一引数なのは少し意外でしたが 雛型を決める引数と考えればそれほどおかしくないような気もしてきました。 しかし引数12個とはすごい数ですね 色々と参考になりました、 ありがとうございました!
intelf___

2016/07/23 13:56

拡張ウィンドウスタイルは、createWindowというもともとあった関数に追加されたものです。 最後に付けると最後に値の受け取り用のポインタがつかないので先頭に付けた、と自分は考えています。拡張ウインドウスタイルは0を指定しても問題ないので重要度は低そうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問