Menu
Coddy logo textTech

new() 関数

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 22/107。

Go には、型のためにメモリを確保し、その型へのポインターを返す new() という組み込み関数があります。確保されたメモリは、その型のゼロ値で初期化されます。

p := new(int)      // int のメモリを割り当てる
fmt.Println(*p)    // 0 (ゼロ値)
fmt.Println(p)     // 0xc000018030 (メモリアドレス)

new()関数は型を引数として受け取り、その型の新しく割り当てられたゼロ値へのpointerを返します。これは、pointerが必要であるものの、参照する既存の変数がない場合に特に便利です。

構造体では、new() はすべてのフィールドがゼロ値に設定された構造体へのポインターを作成します。

type Person struct {
    Name string
    Age  int
}

p := new(Person)
fmt.Println(p.Name)  // "" (空文字列)
fmt.Println(p.Age)   // 0

new()とアドレス演算子&のどちらを使うべきか、疑問に思うかもしれません。以下のどちらの方法も同等です:

// new() を使用
p1 := new(Person)

// リテラルでアドレス演算子を使用
p2 := &Person{}

&Person{}構文のほうが、フィールドを同時に初期化できるため、実際にはより一般的です。ゼロ値のインスタンスが必要で、明示的なメモリ割り当てのセマンティクスを優先する場合は、new()を使用してください。

challenge icon

チャレンジ

簡単

new() がメモリを割り当て、構造体をゼロ値で初期化する仕組みを示す設定マネージャーを作成しましょう。この方法が、構造体リテラルでアドレス演算子を使用する場合とどのように異なるかを確認します。

コードを次の2つのファイルに分けて構成します。

  • config.go: Host(string)、Port(int)、MaxConnections(int)、DebugMode(bool)フィールドを持つ ServerConfig 構造体を定義します。次の2つの関数を作成します。
    • NewServerConfig: new() を使用して ServerConfig を割り当て、ポインターを直接返します(すべてゼロ値)。
    • ConfigureServer: *ServerConfig ポインターと host 文字列および port 整数を受け取り、ポインターを通じて config のそれらのフィールドを設定します。
    さらに、*ServerConfig に、すべての設定値を表示するフォーマット済み文字列を返す Display メソッドを追加します。
  • main.go: 入力から host と port を読み取ります。まず、NewServerConfig() を使用して config を作成し、ゼロ値を示すために表示します。次に、ConfigureServer を使用して host と port を設定し、更新された値を示すために config をもう一度表示します。

次の入力が提供されます。

  • 1行目: Host 名(string)
  • 2行目: Port 番号(整数)

Display メソッドは、次の正確な形式の文字列を返す必要があります。

Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]

表示結果を2回出力します。1回目は設定前(ゼロ値を示す状態)、2回目は設定後(更新された host と port を示す状態)です。

たとえば、localhost8080 が与えられた場合、出力は次のようになります。

Host: 
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: false

最初の表示ですべてのゼロ値(空の文字列、0、0、false)が示されることに注目してください。これは、new() がすべてをゼロ値で初期化するためです。ConfigureServer を呼び出した後は、host と port だけが変更され、その他のフィールドはゼロ値のままです。

自分で試してみよう

package main

import (
	"fmt"
)

func main() {
	// 入力を読み取る
	var host string
	var port int
	fmt.Scanln(&host)
	fmt.Scanln(&port)

	// TODO: NewServerConfig() を使用して設定を作成し、それを表示する
	// これによりゼロ値が表示されます

	// TODO: ConfigureServer を使用してホストとポートを設定する

	// TODO: 更新された値を表示するために設定を再度表示する
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ