🎉

フロントエンドエンジニアのためのGo入門:変数と関数をサクッと理解しよう!

2024/08/24に公開

はじめに

Goはシンプルで効率的な言語ですが、TypeScript(Javascript)の経験のあるフロントエンドエンジニアが初めて学ぶ際には、いくつかの独特なポイントで戸惑ったので記事にしました。
フロントエンドエンジニアがGoを学ぶ際につまづきやすい点をわかりやすく解説し、それぞれの言語の比較コードを示します。
この記事はA Tour of GoのBasicsの一部をピックアップしました。

https://go-tour-jp.appspot.com/list

エクスポートされた名前

Goでは、名前が大文字で始まる場合、その名前はパッケージ外から参照できる「エクスポートされた名前」になります。TypeScriptでも同様にエクスポートの概念がありますが、違いは大文字小文字によってエクスポートが決まる点です。
Goでは、大文字で始まる Name フィールドがパッケージ外から参照可能です。一方で、name のように小文字で始まるフィールドはパッケージ内でしか参照できません。

export class User {
  constructor(public name: string) {}
}
package user

type User struct {
    Name string
}

引数の型省略

Goでは、複数の引数が同じ型である場合、最後の型を残して他の型を省略できます。
これはTypeScriptにはない特有の機能です。

function add(x: number, y: number): number {
  return x + y;
}
func add(x, y int) int {
    return x + y
}

複数の戻り値

Goでは、関数が複数の戻り値を返すことができます。TypeScriptではタプルを使って同様のことができますが、Goはこの機能が標準的です。
Goでは、複数の戻り値を括弧でまとめて返すことができます。

function divide(x: number, y: number): [number, boolean] {
  if (y === 0) {
    return [0, false];
  }
  return [x / y, true];
}
func divide(x, y int) (int, bool) {
    if y == 0 {
        return 0, false
    }
    return x / y, true
}

名前付き戻り値

Goでは、関数の戻り値に名前を付けることができます。これにより、戻り値用の変数を事前に宣言しておき、関数内でその変数に値を割り当てるだけで済むようになります。
Goでは、fullName という名前付き戻り値を使って、return 文を簡潔にすることができます。

function getFullName(firstName: string, lastName: string): string {
  return `${firstName} ${lastName}`;
}
func getFullName(firstName, lastName string) (fullName string) {
    fullName = firstName + " " + lastName
    return
}

短縮記法

Goでは := を使って暗黙的に型を推論しつつ変数を宣言できます。これはTypeScriptの let や const に似ていますが、Go独自の特徴として型推論が直接行われます。
どちらも変数の型を明示的に書かなくても、自動的に推論されます。

let age = 30; // TypeScriptが自動的に型を推論する
age := 30 // Goが自動的に型を推論する

条件文での簡易ステートメント

Goでは、if 文の条件の前に簡単なステートメントを書くことができます。これはTypeScriptにはないGo特有の機能です。
Goでは、if 文の中で変数を宣言し、その変数を条件に使うことができます。

let result = calculate();
if (result > 0) {
  console.log("Positive");
}
if result := calculate(); result > 0 {
    fmt.Println("Positive")
}

defer

deferは、Goで特定の関数が終了する直前に実行するコードを予約するために使われます。
一方、TypeScript(JavaScript)には直接的なdeferはありませんが、tryを使えば似たようなことができます。

function main() {
    console.log("Start");
    try {
        console.log("Doing something...");
    } finally {
        console.log("End");
    }
    console.log("This is deferred");
}

main();
Start
Doing something...
End
This is deferred
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Start")
    
    // defer ステートメントで最後に実行する処理を指定
    defer fmt.Println("This is deferred")
    
    fmt.Println("Doing something...")
    
    // 関数の最後で defer された処理が実行される
    fmt.Println("End")
}
Start
Doing something...
End
This is deferred

終わりに

GoとTypeScriptの違いや共通点を理解することで、新しい言語の学習がよりスムーズになるはずです。
Goのシンプルで強力な構文を活用し、より効率的に開発を進められるようになっていただければ幸いです。
最後までお読みいただきありがとうございます!

Discussion