- 投稿日:2020-03-25T17:33:31+09:00
Goでのint型変数の絶対値出力
はじめに
Go言語でPaizaを解いていた時に絶対値の出力で詰まったためメモ。
初学者のため誤り等ありましたらご指摘ください。
Goバージョン:1.13.8Goでの絶対値の出力方法
下記のようにint型の変数aをmath.Absを使用し絶対値を出力しようとした場合、エラーとなった。
エラーとなったコード
package main import ( "fmt" "math" ) func main() { var a int a = -1 fmt.Println(math.Abs(a)) }cannot use a (type int) as type float64 in argument to math.Absどうやらmath.Absではfloat64の型しか許容していないよう。
正常に動作したコード
int型の変数aをfloat64型にキャスト変換した上でmath.Absにて絶対値を取得。その値を変数bに設定。
整数で出力するために変数bをint型に変換して出力。package main import ( "fmt" "math" ) func main() { var a int var b float64 a = -1 b = math.Abs(float64(a)) // float64型にキャスト変換し、変数bに絶対値を設定 fmt.Printf("%d", int(b)) // 整数で出力するためにint型に変換し出力。 }出力結果
1
- 投稿日:2020-03-25T17:33:31+09:00
Golangでのint型変数の絶対値取得
はじめに
Go言語でPaizaを解いていた時に絶対値の取得で詰まったためメモ。
初学者のため誤り等ありましたらご指摘ください。
Goバージョン:1.13.8Goでの絶対値の取得方法
下記のようにint型の変数aをmath.Absを使用し、絶対値を取得しようとした場合、エラーとなる。
エラーとなったコード
package main import ( "fmt" "math" ) func main() { var a int a = -1 fmt.Println(math.Abs(a)) }cannot use a (type int) as type float64 in argument to math.Absどうやらmath.Absではfloat64の型しか許容していないよう。
正常に動作したコード
下記のようにint型の変数aをfloat64にキャスト変換すると正常に出力された。
package main import ( "fmt" "math" ) func main() { var a int a = -1 fmt.Println(math.Abs(float64(a))) }
- 投稿日:2020-03-25T17:33:31+09:00
Goでのint型変数の絶対値取得
はじめに
Go言語でPaizaを解いていた時に絶対値の取得で詰まったためメモ。
初学者のため誤り等ありましたらご指摘ください。
Goバージョン:1.13.8Goでの絶対値の取得方法
下記のようにint型の変数aをmath.Absを使用し、絶対値を取得しようとした場合、エラーとなる。
エラーとなったコード
package main import ( "fmt" "math" ) func main() { var a int a = -1 fmt.Println(math.Abs(a)) }cannot use a (type int) as type float64 in argument to math.Absどうやらmath.Absではfloat64の型しか許容していないよう。
正常に動作したコード
下記のようにint型の変数aをfloat64にキャスト変換すると正常に出力された。
package main import ( "fmt" "math" ) func main() { var a int a = -1 fmt.Println(math.Abs(float64(a))) }
- 投稿日:2020-03-25T07:14:48+09:00
Golangで、デザインパターン「Bridge」を学ぶ
GoFのデザインパターンを学習する素材として、書籍「増補改訂版Java言語で学ぶデザインパターン入門」が参考になるみたいですね。
取り上げられている実例は、JAVAベースのため、Pythonで同等のプラクティスに挑んだことがありました。
Qiita記事: "Pythonで、デザインパターン「Bridge」を学ぶ"今回は、Pythonで実装した”Bridge”のサンプルアプリをGolangで実装し直してみました。
■ Bridge(ブリッジ・パターン)
Bridgeパターン(ブリッジ・パターン)とは、GoF(Gang of Four; 4人のギャングたち)によって定義されたデザインパターンの1つである。 「橋渡し」のクラスを用意することによって、クラスを複数の方向に拡張させることを目的とする。
UML class and sequence diagram
UML class diagram
□ 備忘録
Bridgeパターンは、機能のクラス階層と実装のクラス階層を橋渡しするらしいです。
(1) 機能のクラス階層とは?
あるクラスに対して、新しい機能を追加したい場合、新しくサブクラスを定義した上で、メソッドを実装します。
既存のスーパークラスと、新たに定義したサブクラスの関係が、"機能のクラス階層"になります。
一般的には、以下のような関係を想定します。
- スーパークラスは基本的な機能を持っている
- サブクラスで新しい機能を追加する
(2) 実装のクラス階層とは?
新しい実装を追加したい場合、抽象クラスから派生した具体的なサブクラスを定義した上で、メソッドを実装します。
既存の抽象クラスと、新たに派生した具体的なサブクラスの関係が、"実装のクラス階層"になります。
一般的には、以下のような関係を想定します。
- 抽象クラスでは、抽象メソッドによってインタフェースを規定している
- 派生したサブクラスは具象メソッドによってそのインタフェースを実装する
■ "Bridge"のサンプルプログラム
実際に、Bridgeパターンを活用したサンプルプログラムを動かしてみて、次のような動作の様子を確認したいと思います。
機能のクラス階層と実装のクラス階層を橋渡しを想定したサンプルになります。
DisplayFunc
と、DisplayStringImpl
の橋渡しを経て、文字列を表示するDisplayCountFunc
と、DisplayStringImpl
の橋渡しを経て、文字列を表示するDisplayCountFunc
と、DisplayStringImpl
の橋渡しを経て、文字列を表示するDisplayRandomFunc
と、DisplayStringImpl
の橋渡しを経て、文字列を5回繰り返して表示するDisplayRandomFunc
と、DisplayStringImpl
の橋渡しを経て、文字列をランダム回数繰り返して表示するDisplayFunc
と、DisplayTextfileImpl
の橋渡しを経て、テキストファイルの内容を表示する$ go run Main.go +-----------+ |Hello Japan| +-----------+ +-----------+ |Hello Japan| +-----------+ +--------------+ |Hello Universe| +--------------+ +--------------+ |Hello Universe| |Hello Universe| |Hello Universe| |Hello Universe| |Hello Universe| +--------------+ +--------------+ |Hello Universe| |Hello Universe| +--------------+ aaa bbb ccc ddd eee fff gggサンプルプログラムを動かしただけだと、いまいち、何がしたいのかよく分かりませんね。
つづいて、サンプルプログラムの詳細を確認していきます。■ サンプルプログラムの詳細
Gitリポジトリにも、同様のコードをアップしています。
https://github.com/ttsubo/study_of_design_pattern_with_golang/tree/master/Bridge
- ディレクトリ構成
. ├── Main.go ├── bridge │ ├── display_count_func.go │ ├── display_func.go │ ├── display_impl.go │ ├── display_random_func.go │ ├── display_string_impl.go │ └── display_textfile_impl.go └── test.txt(1) Abstraction(抽象化)の役
Implement
役のメソッドを使って、基本的な機能だけが実装されているクラスです。
サンプルプログラムでは、DisplayFunc
構造体が、この役を努めます。bridge/display_func.gopackage bridge // DisplayFunc is struct type DisplayFunc struct { impl displayImpl } // NewDisplayFunc func for initializing DisplayFunc func NewDisplayFunc(impl displayImpl) *DisplayFunc { return &DisplayFunc{ impl: impl, } } func (d *DisplayFunc) open() { d.impl.rawOpen() } func (d *DisplayFunc) printBody() { d.impl.rawPrint() } func (d *DisplayFunc) close() { d.impl.rawClose() } //Display func for displaying string func (d *DisplayFunc) Display() { d.open() d.printBody() d.close() }(2) RefinedAbstraction(改善した抽象化)の役
Abstraction
役に対して機能を追加した役です。
サンプルプログラムでは、DisplayCountFunc
構造体と、DisplayRandomFunc
構造体が、この役を努めます。bridge/display_count_func.gopackage bridge // DisplayCountFunc is struct type DisplayCountFunc struct { *DisplayFunc } // NewDisplayCountFunc func for initializing DisplayCountFunc func NewDisplayCountFunc(impl displayImpl) *DisplayCountFunc { return &DisplayCountFunc{ DisplayFunc: &DisplayFunc{ impl: impl, }, } } //MultiDisplay func for displaying string func (d *DisplayCountFunc) MultiDisplay(times int) { d.open() for i := 0; i < times; i++ { d.printBody() } d.close() }bridge/display_random_func.gopackage bridge import ( "math/rand" "time" ) // DisplayRandomFunc is struct type DisplayRandomFunc struct { *DisplayFunc } // NewDisplayRandomFunc func for initializing DisplayRandomFunc func NewDisplayRandomFunc(impl displayImpl) *DisplayRandomFunc { return &DisplayRandomFunc{ DisplayFunc: &DisplayFunc{ impl: impl, }, } } //RandomDisplay func for displaying string func (d *DisplayRandomFunc) RandomDisplay(times int) { d.open() rand.Seed(time.Now().UnixNano()) randomTimes := rand.Intn(times) for i := 0; i < randomTimes; i++ { d.printBody() } d.close() }(3) Implementor(実装者)の役
Abstraction
役のインタフェースを実装するためのメソッドを規定する役です。
サンプルプログラムでは、DisplayImpl
インタフェースが、この役を努めます。bridge/display_impl.gopackage bridge type displayImpl interface { rawOpen() rawPrint() rawClose() }(4) ConcreteImplementor(具体的な実装者)の役
具体的に
Implement
役のインタフェースを実装する役です。
サンプルプログラムでは、DisplayStringImpl
構造体と、DisplayTextfileImpl
構造体が、この役を努めます。bridge/display_string_impl.gopackage bridge import ( "fmt" "strings" ) // DisplayStringImpl is struct type DisplayStringImpl struct { str string width int } // NewDisplayStringImpl func for initializing DisplayStringImpl func NewDisplayStringImpl(str string) *DisplayStringImpl { return &DisplayStringImpl{ str: str, width: len(str), } } func (d *DisplayStringImpl) rawOpen() { d.printLine() } func (d *DisplayStringImpl) rawPrint() { fmt.Printf("|%s|\n", d.str) } func (d *DisplayStringImpl) rawClose() { d.printLine() fmt.Println("") } func (d *DisplayStringImpl) printLine() { line := strings.Repeat("-", d.width) fmt.Printf("+%s+\n", line) }bridge/display_textfile_impl.gopackage bridge import ( "fmt" "os" ) // DisplayTextfileImpl is struct type DisplayTextfileImpl struct { fileName string f *os.File } // NewDisplayTextfileImpl func for initializing DisplayTextfileImpl func NewDisplayTextfileImpl(str string) *DisplayTextfileImpl { return &DisplayTextfileImpl{ fileName: str, } } func (d *DisplayTextfileImpl) rawOpen() { fp, err := os.Open(d.fileName) if err != nil { panic(err) } else { d.f = fp } } func (d *DisplayTextfileImpl) rawPrint() { buf := make([]byte, 64) _, err := d.f.Read(buf) if err != nil { panic(err) } fmt.Printf("%s\n", buf) } func (d *DisplayTextfileImpl) rawClose() { d.f.Close() }(5) Client(依頼人)の役
サンプルプログラムでは、
startMain
関数が、この役を努めます。Main.gopackage main import ( "./bridge" ) func startMain() { d1 := bridge.NewDisplayFunc(bridge.NewDisplayStringImpl("Hello Japan")) d2 := bridge.NewDisplayCountFunc(bridge.NewDisplayStringImpl("Hello Japan")) d3 := bridge.NewDisplayCountFunc(bridge.NewDisplayStringImpl("Hello Universe")) d4 := bridge.NewDisplayRandomFunc(bridge.NewDisplayStringImpl("Hello Universe")) d5 := bridge.NewDisplayFunc(bridge.NewDisplayTextfileImpl("test.txt")) d1.Display() d2.Display() d3.Display() d3.MultiDisplay(5) d4.RandomDisplay(5) d5.Display() } func main() { startMain() }■ 参考URL