0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Golang】無名関数に名前を付けて関数内関数として使う

Posted at

【Golang】無名関数に名前を付けて関数内関数として使う

概要

どうしても関数内で関数を定義したい場合のやつ

モチベーション

関数は大きくても小さくても使いづらい(個人談)
関数内で少しまとめたい機能だけど外に括り出すほどではない、
けど関数内で何回か使う
そんな機能を関数内に関数として定義したかった
(所謂 module 内の function みたいなもの)

結論コード

main.go
package main

import (
	"os"
	"strconv"
)

func main() {

	parsi := func(cstrv string) int {
		i64v, _ := strconv.ParseInt(cstrv, 10, 32)
		return int(i64v)
	}

	cv1 := parsi(os.Args[1])
	cv2 := parsi(os.Args[2])

	println(cv1, "+", cv2, "=", calcAdd(cv1, cv2))
}

func calcAdd(inp1, inp2 int) int {
	return inp1 + inp2
}

Golang の strconv.ParseInt:string -> int64 変換は
2変数を返す関数でかつ 32 と言っているのに int64 で返ってくる

Golang は型にうるさいので、当然 int64, int は型エラーとなる
(つまり int64 では calcAdd 関数は使えない)

Golang は 初回のみ := 代入で宣言等をすっ飛ばして代入できるが、
2回目の代入では = を使う必要があり、コードの単純コピペができない
(つまり中間変数は1回目は := でいいが、2回目は = を用いる必要がある)

そんなこんなで string -> int64 と int へのキャストをまとめた parsi 関数を無名関数で定義し、名前を付けて以降使用している

おまけ

Golang は関数を変数として扱うことができる(上記の通り)

main2.go
package main

var (
	f_add = func(i1, i2 int) int {
		return i1 + i2
	}

	f_sub = func(i1, i2 int) int {
		return i1 - i2
	}
)

func main() {
	v1 := 26
	v2 := 16

	println(v1, "+", v2, "=", calc(v1, v2, f_add))
	println(v1, "-", v2, "=", calc(v1, v2, f_sub))
	println(v1, "x", v2, "=", calc(v1, v2, f_mul))
}

func f_mul(i1, i2 int) int {
	return i1 * i2
}

func calc(inp1, inp2 int, f func(int, int) int) int {
	return f(inp1, inp2)
}

つまりのところ、関数の引数に関数型の変数を突っ込むという考え方で高階関数として扱うことができる
正直某ラムダ式よりこっちの方がわかりやすいのでは・・・?

ただ、この場合の関数は無名関数でなくても良いよ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?