LoginSignup
1
0

More than 3 years have passed since last update.

ゆっくりGo vol.2

Posted at

前回のおさらい

・私にとっての明日は今日なので…(目そらし)
forまで習ったぞ!
・個人的に好きな言語!
・型のあたりがもやもやするぞ!

ほんへ

if.go
//------------------------------------------------
func pow(x, n, lim float64) (float64, float64) {
    if v := math.Pow(x, n); v < lim {
        return v,lim
    }
    return lim
}

func main() {
    fmt.Println(
        pow(3, 2, 10),
        pow(3, 3, 20),
    )
}
//----------------------------------------------

ifと言うより関数が独特に感じる。

上記のコードを走らせると、こんなエラーが返ってくる。

e1.go
./prog.go:12:2: not enough arguments to return
    have (float64)
    want (float64, float64)
./prog.go:17:6: multiple-value pow() in single-value context
./prog.go:18:6: multiple-value pow() in single-value context

内容としては引数と戻り値の数が一致してないよ!ってことっぽい。

原因としては、ifの外側のreturnに戻り値が一つしかない点にある。

それを修正すると、

e2.go
./prog.go:17:6: multiple-value pow() in single-value context
./prog.go:18:6: multiple-value pow() in single-value context

が返ってくる。

単一の変数なのに、中に二つも数字があるよ!ってことっぽい。

この原因はfmt.Println(,)みたいな書き方をしている所にあるっぽい。

色々書き直して、最終的にこんな感じに……

Exacer_if.go
package main

import (
    "fmt"
    "math"
)

func pow(x, n, lim float64) (float64, float64) {
    if v := math.Pow(x, n); v < lim {
        return v, lim
    }
    return lim, n
}

func main() {
    fmt.Println(pow(3, 2, 10))
    fmt.Println(pow(3, 3, 20))
}

一応うまいくいった。

ただ面白いのが、戻り値を省略することができない点。

戻り値の数だけ、きちんと明記しなければならない。

可読性の観点でいえば、非常に重要機能だと思う。

何より、この次も非常に面白かった。

if_else.go
//---------------------------------------------
func pow(x, n, lim float64) float64 {
    if v := math.Pow(x, n); v < lim {
        return v
    } else {
        fmt.Printf("%g >= %g\n", v, lim)
    }
    // can't use v here, though
    return lim
}

func main() {
    fmt.Println(
        pow(3, 2, 10),
        pow(3, 3, 20),
    )
}
//-------------------------------------------

面白いのってfmt.Printf("%g >= %g\n", v, lim)の文。

これってreturnだと戻り値の制約に引っかかる所を、

表示の文を入れることで、それに対処している。

if-returnみたいな思考回路の私には一生思いつかない書き方。

少し詰まったExercise

Newton_Raphson.go
package main

import (
    "fmt"
)

func Sqrt(x float64) int {
    var z float64 = 1
    var i int = 1
    for ; i < 11; i++ {
        z = z - (z*z-x)/(2*z)
        fmt.Print(z, "\n")
    }
    return (i)
}

func main() {
    fmt.Println(Sqrt(2))
}

・iは0+1からスタート
・zをしくじってfor内に書いてしまう

なんてことをしていました。

Switch構文は良いですね!

Fortranのcaseより使い勝手がよさそうです。

……気になるのが、Fortranのcaseって数値だけしか取れないんですかね?

正直一番気になったのはdefer

便利そうな構文で上手に使えれば面白そうでした。

defer.go
//----------------------------------
func main() {
    fmt.Println("counting")

    for i := 0; i < 10; i++ {
        defer fmt.Println(i)
    }

    fmt.Println("done")
}
//---------------------------------

普通なら評価が終わった順に何かしらされますが、

終了した全部の評価を逆順ソートして出力するみたいな動きですかね?

何か悪さができそうですね………

感想

Flow control statements: for, if, else, switch, and defer

まで終了しました。

想定していたスピードよりも大分遅いですが、ぼちぼちとしておきます。

A Tour of Go ですが、

色々とimportについての説明が欠片もないので、

少し大変かなぁと。

1
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
1
0