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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Go

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

13回答

6340閲覧

関数名call1, call2, call3...の連続実行をまとめる方法はありますか?

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Go

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

5グッド

11クリップ

投稿2017/08/31 19:01

編集2017/09/01 08:09

はじめに

後述のコードはGolangで書かれていますが、全言語において気になっていたので多言語のタグをつけさせていただきます。
回答コードは、Go,python , C#ないしCだと助かりますが、その他言語でも問題ありません
正直「そんな方法はありません」
という回答が来る気もしています

特にGoとC#の回答を求めています!

やりたいこと

関数
call1
call2
call3
call4
を定義しておいて、末尾の数字だけを変えて連続実行する際に、綺麗にまとめる方法はありますか?

以下、動かないですが、やろうとしてることが伝わるように、イメージを書いておきます。。

go

1func main() { 2 for i:=1;i<4;i++{ 3 call+i() 4 } 5} 6 7func call1() { 8 fmt.Println("I am call1") 9} 10 11func call2() { 12 fmt.Println("I am call2") 13} 14 15func call3() { 16 fmt.Println("I am call3") 17} 18 19func call4() { 20 fmt.Println("I am call4") 21}

追記

みなさん多彩な回答ありがとうございます。
現状Goで困っていたため、Goで回答を作ってくださった方をベストアンサーとさせていただきますが、他言語を使うことになった際は、ここを参考にさせていただきます。
ありがとうございました!

  • Goは関数の配列を作って、forで回す, あるいはreflectを使う(非推奨)
  • pythonはevalを使う
  • phpは可変関数, call_user_func, あるいはevalを使う(非推奨)
  • JSは関数を配列に入れる, あるいはevalを使う(非推奨)
  • C#はデリゲートを作る, リフレクションを使う

Cとswift, objective-cにも回答がついていました。

募集から1日未満にもかかわらず、たくさんの回答、ありがとうございました。
私のみならず、他の人の参考にもなれば幸いと思います。

Yuki_S, Harinezumi, hineya09👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 08:11

ありがとうございます!
isacRu

2017/09/06 23:42

あぜその方法にこだわるのか、理由も追記してもらえるとありがたいです。最初問題を読んだとき、メインメソッドで実行したい関数を並べれば良いじゃないか。私はそう思いました。
guest

回答13

0

追記:
コメントでご指摘頂きましたが、eval()は脆弱性につながる恐れがありますので、他の手段がある場合は使わないほうが良いようです。PHPにはcall_user_func()という専用関数が、Pythonならばglobals()またはlocals()で定義済みの関数・変数のディクショナリを取得することで文字列での呼び出しができます。

PHP:call_user_func - Manual
2. 組み込み関数 ー Python 3.6.1 ドキュメント

参考までに、PHPの公式ドキュメントには下記のように記載されています。

警告

eval() は非常に危険な言語構造です。 というのも、任意の PHP コードを実行できてしまうからです。 これを使うことはおすすめしません。 いろいろ検討した結果どうしても使わざるを得なくなった場合は、細心の注意を払って使いましょう。 ユーザーから受け取ったデータをそのまま渡してはいけません。 渡す前に、適切な検証が必要です。


肝心のGolangについては門外漢ですので、pythonと、聞かれてないですがPHPの例です。
eval()を使えばなんでもできます(是非はともかくとして)。

pyth

1def call1(): print('spam') 2def call2(): print('ham') 3def call3(): print('sausage') 4 5for i in range(1, 4): 6 eval('call' + str(i) + '()') 7

php

1<?php 2function call1(){ echo "call1"; } 3function call2(){ echo "call2"; } 4function call3(){ echo "call3"; } 5 6foreach (range(1, 3) as $i){ 7 eval('call' . $i . '();'); 8}

投稿2017/08/31 19:27

編集2017/09/03 07:55
tsuemura

総合スコア663

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

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

yambejp

2017/09/01 01:03

他に手段がある場合はなるべくならevalは使わないほうがよいかと
退会済みユーザー

退会済みユーザー

2017/09/01 07:55 編集

python, phpでの回答ありがとうございます! ああ、pythonにはevalがありますね、なるほど phpはcall_user_funcという便利なものを使った回答が上で示されていました。いかがでしょうか
退会済みユーザー

退会済みユーザー

2017/09/01 07:50

ほかに手段。。 定義:$method = "call" . 1; 呼出:$method() とかできた気もする
退会済みユーザー

退会済みユーザー

2017/09/01 07:51

PHP
退会済みユーザー

退会済みユーザー

2017/09/01 07:57

なるほど、、、phpは全く心得がないのですが、今後使う際に参考にさせていただきます! ありがとうございます
tsuemura

2017/09/03 07:57

皆さん、コメント&ご指摘ありがとうございます。eval()の危険性等について回答に追記しました。
退会済みユーザー

退会済みユーザー

2017/09/04 09:31

わざわざありがとうございます
guest

0

ベストアンサー

Go言語の関数は変数に格納できるという特徴を持っています。(第一級関数という特徴です。JavaScript等も同様)

この特徴を利用し、例えば配列に関数を追加して、イテレータ(i)で呼び出した関数を順次実行するということが出来ます。

このような方法でなくとも、「Go言語の関数は変数に格納できる」という特徴を上手く利用すれば似たようなことはかなり自由自在にできます。
是非考えてみて下さい。

以下、手直ししてみました。
私の環境では動作することを確認しています。

Go

1func main() { 2 3 var funcList [4]func() 4 funcList[0] = call1 5 funcList[1] = call2 6 funcList[2] = call3 7 funcList[3] = call4 8 9 for i:=0;i<4;i++{ 10 f := funcList[i] 11 f() 12 } 13} 14 15func call1() { 16 fmt.Println("I am call1") 17} 18 19func call2() { 20 fmt.Println("I am call2") 21} 22 23func call3() { 24 fmt.Println("I am call3") 25} 26 27func call4() { 28 fmt.Println("I am call4") 29}

イメージ説明

投稿2017/09/01 03:16

akabee

総合スコア1947

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:54

Golangでの回答ありがとうございます! 関数を変数に格納できるのですね! 知りませんでした。 上の方はfor rangeで回してらっしゃいました。どちらもありですね!
akabee

2017/09/01 07:59

for rangeはintelf___さんの回答のことですよね。そのとおり、色々とやり方はあります。 要するに複数のものを格納して取り出せるものに対して関数を格納し、任意の順に取り出して関数を実行すれば実現できます。 そういう意味では配列であってもスライスであっても基本となる考え方は同様ですね。
guest

0

c言語で書いてみました。綺麗とは言えませんが。

c

1#include <stdio.h> 2 3int call1(int a) { return(a+10); } 4int call2(int a) { return(a+20); } 5int call3(int a) { return(a+30); } 6int call4(int a) { return(a+40); } 7 8void main() 9{ 10 int (*po[])() = { call1, call2, call3, call4 }; 11 12 int i; 13 for (i=0;i<4;i++){ 14 printf("Call Func call%d\n",(*po[i])(i)); 15 } 16}

投稿2017/09/01 00:07

編集2017/09/01 00:41
A.Ichi

総合スコア4070

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:55 編集

Cでの回答ありがとうございます! 関数ポインタというやつを使っているんですかね?
guest

0

PHPなら可変関数が使えるのですが、他の言語(JavaScript/Python)であれば eval とかを使う方法があるようです。JavaScriptであればそもそも配列に関数自体を入れることができるので、evalを使わなくても良いと思います。

JavaScript

1const func = [ 2 i=>{ console.log( 1, i ); } 3 , i=>{ console.log( 2, i ); } 4 , i=>{ console.log( 3, i ); } 5]; 6func.map( ( f, i )=>{ f( i ); } ); 7/* 81 0 92 1 103 2 11*/

【PHP: 可変関数 - Manual】
http://php.net/manual/ja/functions.variable-functions.php

【JavaScriptでPHPの可変関数のような事をしたい時は | nkymemo】
http://nkymemo.blogspot.jp/2011/02/javascriptphp.html

【Python - 関数を文字列から動的に呼び出す - Qiita】
http://qiita.com/Chan_moro/items/9b0105e4c18bb76ed4e9

【python - Pythonで可変関数の書き方を教えてください。 - スタック・オーバーフロー】
https://ja.stackoverflow.com/questions/32744/pythonで可変関数の書き方を教えてください/32748

投稿2017/08/31 19:20

kei344

総合スコア69583

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:55 編集

js, python, phpでの回答ありがとうございます! なるほど。pythonならevalを使うしかないのでしょうか? それと、そもそも私がやりたいのは可変関数というものなのでしょうか
guest

0

Objective-C

objectivec

1- (void)call1 {NSLog(@"call1");} 2- (void)call2 {NSLog(@"call2");} 3- (void)call3 {NSLog(@"call3");} 4- (void)call4 {NSLog(@"call4");} 5 6for (int i = 1; i <= 4; i++) { 7 NSString *name = [NSString stringWithFormat:@"call%zd", i]; 8 SEL sel = NSSelectorFromString(name); 9 if ([self respondsToSelector:sel]) { 10 [self performSelector:sel]; 11 } else { 12 NSLog(@"'%@' does not exist.", name); 13 } 14}

Swift (with Objective-C)

swift

1@objc func call1() {print("@call1")} 2@objc func call2() {print("@call2")} 3@objc func call3() {print("@call3")} 4@objc func call4() {print("@call4")} 5 6for i in 1...4 { 7 let name = "call\(i)" 8 let sel = Selector(name) 9 if self.responds(to: sel) { 10 self.perform(sel) 11 } else { 12 print("'\(name)' does not exist.") 13 } 14}

Swift

akabeeさんの回答を書き直してみました。

swift

1func call1() {print("call1")} 2func call2() {print("call2")} 3func call3() {print("call3")} 4func call4() {print("call4")} 5 6let funcList = [call1, call2, call3, call4] 7funcList.forEach {$0()} 8 9//もしくは、 10 11let funcList = [call1(), call2(), call3(), call4()] 12funcList.forEach {$0}

投稿2017/09/01 01:07

編集2017/09/01 08:25
fuzzball

総合スコア16733

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:55 編集

objc, swiftでの回答ありがとうございます! objective-cはさすがに使わないものの、swiftは少しだけ心得があるので、今後の参考になります!
guest

0

PHPでは専用関数がよういされています

PHP

1for($i=1;$i<=3;$i++){ 2call_user_func("call".$i); 3} 4function call1(){ 5 print "a"; 6} 7function call2(){ 8 print "b"; 9} 10function call3(){ 11 print "c"; 12} 13

投稿2017/09/01 01:02

yambejp

総合スコア116412

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:55 編集

PHPでの回答ありがとうございます! PHPだととても綺麗にまとまるんですね〜。。驚きです
guest

0

デリゲートtestを作成して、そこに呼び出したい関数を設定する。
test()にてすべての関数を実行する。

C#

1 public Form1() 2 { 3 InitializeComponent(); 4 5 Action test = null; 6 test += Call1; 7 test += Call2; 8 test += Call3; 9 test += Call4; 10 test(); 11 } 12 13 void Call1() 14 { 15 System.Diagnostics.Debug.WriteLine("call1"); 16 } 17 18 void Call2() 19 { 20 System.Diagnostics.Debug.WriteLine("call2"); 21 } 22 23 void Call3() 24 { 25 System.Diagnostics.Debug.WriteLine("call3"); 26 } 27 28 void Call4() 29 { 30 System.Diagnostics.Debug.WriteLine("call4"); 31 }

投稿2017/09/01 04:28

kikukiku

総合スコア529

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:40

回答ありがとうございます!デリゲートを作ればいいんですね...なるほど!綺麗にまとまっていて、驚きました。
guest

0

こうですか?

C#

1using System; 2using System.Linq; 3 4namespace ConsoleApplication1 5{ 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 Enumerable.Range(1, 4) 11 .Select(n => "Call" + n) 12 .Select(m => typeof(Hoge).GetMethod(m)) 13 .ToList() 14 .ForEach(m => m.Invoke(null, null)); 15 } 16 17 class Hoge 18 { 19 public static void Call1() 20 { 21 Console.WriteLine("call1"); 22 } 23 24 public static void Call2() 25 { 26 Console.WriteLine("call2"); 27 } 28 29 public static void Call3() 30 { 31 Console.WriteLine("call3"); 32 } 33 34 public static void Call4() 35 { 36 Console.WriteLine("call4"); 37 } 38 } 39 } 40}

投稿2017/09/01 04:16

hihijiji

総合スコア4152

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:41

回答ありがとうございます! 上にデリゲートを使った手法の回答がありますが、また違う回答ありがとうございます。 参考になります。
guest

0

英文ですが、実現できるようです。
https://stackoverflow.com/questions/8103617/call-a-struct-and-its-method-by-name-in-go
構造体の値(メソッド)をreflectパッケージによって取り出して実行しています。

ただ、reflectパッケージはプログラムを複雑にするだけでなく実行速度の低下にもつながるので、むやみな使用は避けましょう。

以下のようにしたほうが無難かと思われます。

go

1funcs := []func(){call1, call2, call3, call4} 2for _, f := range funcs { 3 f() 4}

投稿2017/09/01 04:03

intelf___

総合スコア868

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:52

Golangでの回答ありがとうございます! 要は、関数をスライスに入れて、forで回せるということですね? 関数でスライスを作れるんですね。 知りませんでした
intelf___

2017/09/02 12:08

はい、golangはファーストクラスオブジェクト(第一級オブジェクト)という仕組みを持っているのでこういったことが出来ます。 上記for文は、Javascript等のファーストクラスオブジェクトに対応している言語なら利用出来るかと思います。
guest

0

例だけ見るとこうすればできますが。

C#

1static void Main(string[] args) 2{ 3 for (int i = 1; i <= 4; i++) 4 { 5 Call(i); 6 } 7} 8 9static void Call(int i) 10{ 11 Console.WriteLine("I am call{0}", i); 12}

リフレクションで動的に関数名を指定したいということでしょうか。

C#

1class Program 2{ 3 static void Main(string[] args) 4 { 5 TestClass tc = new TestClass(); 6 Type t = tc.GetType(); 7 for (int i = 1; i <= 4; i++) 8 { 9 MethodInfo mi = t.GetMethod(string.Format("Call{0}", i)); 10 mi.Invoke(tc, new object[] { }); 11 } 12 13 Console.ReadLine(); 14 } 15} 16 17class TestClass 18{ 19 public void Call1() 20 { 21 Console.WriteLine("I am call1"); 22 } 23 public void Call2() 24 { 25 Console.WriteLine("I am call2"); 26 } 27 public void Call3() 28 { 29 Console.WriteLine("I am call3"); 30 } 31 public void Call4() 32 { 33 Console.WriteLine("I am call4"); 34 } 35}

投稿2017/09/01 02:13

編集2017/09/01 05:56
workaholist

総合スコア559

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:54 編集

C#での回答ありがとうございます! 上にデリゲートを使った手法の回答がありますが、また違う回答ありがとうございます。 参考になります。
guest

0

多言語ということで

call4までしかないけど 5,6,7って増えたら forの数字を修正しないといけないですよね。
どうせコードをいじるのであれば、、、
callをすべて関数ポインタ(およびそれに準じるもの)にしておいて関数ポインタの配列をforで回して実行。
うまくplugin形式にしておいてメイン実装修正しなくても実行できるようにしてみるといいね。

投稿2017/08/31 20:02

Tak1016

総合スコア1408

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

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

退会済みユーザー

退会済みユーザー

2017/09/01 07:48

回答ありがとうございます! そうですね。おっしゃる通りです。
guest

0

;;; Common Lispでのケースです。

Lisp

1(defun call1() 2 (print "call1")) 3 4(defun call2() 5 (print "call2")) 6 7(defun call3() 8 (print "call3")) 9 10(defun join (str lst &optional (jstr "")) 11 (cond 12 ((null lst) jstr) 13 (t (let ((news (concatenate 'string jstr 14 (first lst) 15 (if (null (rest lst)) 16 "" 17 str)))) 18 (join str (rest lst) news))))) 19 20(defun call-fn() 21 (dolist(a '("1" "2" "3")) 22 (funcall 23 (read-from-string 24 (join "" `("call" ,a)))))) 25 26(call-fn) 27

投稿2017/09/07 00:39

t-cool

総合スコア71

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

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

0

解決済みだけれど、Rubyでの回答が無かったので参考までに。

ruby

1def call1 2 puts 'call1' 3end 4def call2 5 puts 'call2' 6end 7def call3 8 puts 'call3' 9end 10 11(1..3).each {|i| send("call#{i}") } #

投稿2017/09/06 08:48

編集2017/09/06 08:49
philomagi

総合スコア267

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

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

退会済みユーザー

退会済みユーザー

2017/09/06 10:31

回答ありがとうございます。 なるほど、ここを見た他の方の参考にもなるかと思います。 ベストアンサーが決まっているにも関わらず、わざわざありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問