/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

2018/11/08 SlackAPI, 三項演算子, goto文

飾り棚を少しずつ冬っぽくしようと、昨日夜飾り付けをしていました。マリボウルはクリアしか持っていないのですが、火をつけると雰囲気が華やかで良いですね。サルパネヴァプレートに写る様子もとてもきらびやか。

f:id:bynatures:20181108115653j:plain

Slack の API を呼ぶ

Slack の API を通じて、チャネルに通知を飛ばしたかったので調査。すごい簡単でした。昔 Twitter の API に投稿しようとして面倒だった記憶があったのですが、Slack は Webhook URL を取得したらほぼ完了です。あとは JSON を POST するだけでした。

crossbridge-lab.hatenablog.com

三項演算子がない

Go言語には三項演算子(tenary operator)がないので、プログラムが冗長になる場面が多いです。思想として、書きやすさよりも(他のプログラマに対して)読みやすさを重視しているから…ということなのですが。

stackoverflow.com

それでも三項演算子があれば

int index = val > 0 ? val : -val

と書けるはずが

var index int
if val > 0 {
    index = val
} else {
    index = -val
}

では冗長すぎないかということで上の StackOverflow の質問が投稿されていました。確かに上のプログラムだとかなり読みづらいですが、初期値を与えて else 節を消してしまえば読みやすくなると。

index := val
if val <= 0 {
    index = -val
}

確かにこれなら、どちらが主な値かを示すこともできるし読みやすいです。納得しつつ、でもプログラムを書いて、やっぱり三項演算子欲しいなぁと思うことを繰り返す昨今。。

goto 文を使ってみる

エラー値を受け取って if 文でリターンという処理が何度も続いたので、エラー処理をまとめるために goto 文を使ってみることにしました。ただ、ラベルを貼った移動先にスキップする行の中で、今まで出てきていない変数が新たに宣言されている(スコープに変数が新しく加わる)場合は構文エラーとなります。

cmd/compile: spurious "goto label jumps over declaration" - 2 · Issue #22101 · golang/go · GitHub

この X は goto とラベル宣言の間にいるのでエラーとなります:

package main
func main() {
    goto label
    X := 0
label:
}

変数スコープをややこくしないために、または実装上の都合かもしれませんが、エラー処理をまとめたいといった場合は少々面倒です。変数宣言を関数先頭にまとめてしまうか、新たにブロックを作って以下のようにすることで解決できました:

func main() {
    goto label
    {
        X := 0
        // X を使った処理...
        // もちろん中でも goto できる
    }
label:
}