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

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

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

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

Q&A

解決済

2回答

638閲覧

Go言語でswitch文を大量に使わずに、関数への分岐を行う方法

xxx10

総合スコア1

Go

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

0グッド

0クリップ

投稿2023/09/28 13:54

実現したいこと

実現したいのは文字列の入力に応じて関数を分岐する処理の実装です

仮に以下のように、関数があったとして、入力に応じて実行する関数を分岐することを考えます。
この方法だと確かに分岐が行えていますが、入力のパターンが100などになるとswitch文がとてつもないことになり大変です。

go

1 2package main 3 4import "fmt" 5 6func xxx1() { 7 fmt.Println("pattern1") 8} 9 10func yyy() { 11 fmt.Println("pattern2") 12} 13 14func zzz() { 15 fmt.Println("pattern3") 16} 17 18func main() { 19 var str string 20 fmt.Scan(&str) 21 22 // strが"xxx"の場合はxxx1()を実行 23 // strが"yyy"の場合はyyy()を実行 24 // strが"zzz"の場合はzzz()を実行 25 26 switch str { 27 case "xxx": 28 xxx1() 29 case "yyy": 30 yyy() 31 case "zzz": 32 zzz() 33 } 34 35} 36

そのため、何か他の方法を利用してプログラムの分岐を行いたいと考えているのですが、上記のプログラムより良いものはあったりしますでしょうか?

試したこと

構造体を利用して実装するのを考えいました

go

1type Func func() interface{} 2 3type Service struct { 4 Test Func 5} 6 7var ( 8 httpd = &Service{ 9 Test: func() interface{} { 10 return nil 11 }, 12 } 13) 14 15 16var ( 17 List = map[string]Service{ 18 "httpd": *httpd, 19 } 20)

上記のようにすることで実行するときはList["string"].Testという形で実行できます。ただ、これでも少しブサイクな実装だと感じています。正しい実装方法があれば教えていただきたいです

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

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

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

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

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

guest

回答2

0

ベストアンサー

感想です。

入力のパターンが100などになるとswitch文がとてつもないことになり大変です。

本当に、まったく規則性がなくてそれぞれ異なっているとしか言えない100のパターンがあるのでしょうか。もしもそうなら、そのパターンをすべて書き下すしかないのでどう書いても大差ないと思います。また、コンパイルするとどうせジャンプテーブルかなにかを使って最適化されるのでswitch文が長くなることを気にする必要はないと思います。

そういう巨大な条件分岐をswitch文にするの、私は好きですけどね。

実例。たとえば、この関数のソースコードはGoコンパイラの一部ですが、後のほうにけっこう長いswitch文がありますね。コンパイラでのトークン毎の処理などは全ての場合を列挙するしかないものですが、Go自身でもそのような処理の記述にswitch文を使っているということは、これ以上によいものはないということなのではないでしょうか。

こういう「とてつもない」switch文はCでもよく見られたもの () ですし、それが特に悪いことだとは考えられていなかったからこそGoにも受け継がれたのでしょう (ケース毎にbreakを入れなくてもよくなったのは改善ですね)。私は、多数の場合分けを簡素に表現できてメンテナンスもしやすいと思うので「大変」とは感じません。

感想でした。

投稿2023/09/29 04:01

編集2023/10/02 03:22
ikedas

総合スコア4343

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

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

0

入力のパターンが100などになるとswitch文がとてつもないことになり大変です。

map で jump table を作成する方法が考えられますが、100 個の対応を書き下して適切にメンテナンスし続ける必要があると思うので、本質的に switch 文と大差ないかもしれません。
入力文字列と関数名が完全に一致するのであれば reflection でどうにかできるかもしれませんが…

golang

1package main 2 3import "fmt" 4 5func xxx1() { 6 fmt.Println("pattern1") 7} 8 9func yyy() { 10 fmt.Println("pattern2") 11} 12 13func zzz() { 14 fmt.Println("pattern3") 15} 16 17func main() { 18 var str string 19 tbl := map[string]func(){ 20 "xxx": xxx1, "yyy": yyy, "zzz": zzz, 21 } 22 23 fmt.Scan(&str) 24 if f := tbl[str]; f != nil { 25 f() 26 } 27}

投稿2023/09/28 14:30

melian

総合スコア19825

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問