日曜日, 8月 24, 2025
日曜日, 8月 24, 2025
- Advertisment -

Go1.25 New Features



Go1.25が8月13日にリリースされ、リリースノートブログが公開されています。この記事では前回のGo1.24 New Features に引き続き、Go1.25の新機能の中から気になった機能を紹介していきます。

https://go.dev/doc/go1.25

spec

Go1.25では既存のGoのコードに影響を与える言語仕様の変更はありません。ただし、core typeの概念が削除され、専用の文章に置き換えられました。
詳細については、公式ブログをご参照ください。

https://go.dev/blog/coretypes

https://go.dev/issue/70128

go command

go build -asanオプションは、プログラム終了時にデフォルトでメモリリークを検出するようになりました。
これは、Cによって割り当てられたメモリが解放されず、CまたはGoによって割り当てられた他のメモリから参照されていない場合にエラーを出します。
このエラーは、ASAN_OPTIONS=detect_leaks=0を設定することで無効にできます。

https://github.com/golang/go/issues/67833


事前にビルドされたツールが一部リリースに含まれなくなります。コンパイラやリンカなどのコアツールチェーンのバイナリは引き続き含まれますが、ビルドやテスト、フォーマットで頻繁に呼び出されないツールは含まれません。

削除対象となるツールはaddr2linebuildidnmobjdumppproftest2jsontraceなどです。これらのツールのソースコードは引き続きGOROOTに含まれるため、初回実行時に自動的にビルドされ、キャッシュされます。既存のワークフローに影響を与えることなく、配布パッケージのサイズを大幅に縮小することが可能になります。
参考としてgo1.x.linux-amd64.tar.gzのサイズは1.24.0が75MBなのに対し、1.25.0が57MBと削減されています。

https://go.dev/issue/71867

https://github.com/golang/go/blob/go1.25.0/src/cmd/dist/build.go#L1396-L1406


新しいgo.modignoreディレクティブを使用して、goコマンドが無視するディレクトリを指定できます。指定したディレクトリとそのサブディレクトリ内のファイルは、all./...などのパターンにマッチするとき無視されますが、モジュールのzipファイルには引き続き含まれます。

この機能は、多言語プロジェクトにおいて特に有用です。例えば、node_modulesやBazelが生成するbazel-*ディレクトリなど、大量のファイルを含むディレクトリがある場合、go build ./...go test ./...の実行時間を大幅に短縮できます。また、goplsのCPU使用率も改善されます。

使用例

// go.mod
module example.com/myproject

go 1.25

ignore node_modules
ignore bazel-*
ignore .build

https://go.dev/issue/42965


新しいgo doc -httpオプションは、要求されたオブジェクトのドキュメントを表示するドキュメントサーバーを起動し、ブラウザでドキュメントを表示します。

https://go.dev/issue/68106


新しいgo version -m -jsonオプションは、指定されたGoのバイナリファイルに埋め込まれたビルド情報(runtime/debug.BuildInfo)をJSON形式で出力します。

type BuildInfo struct {
    GoVersion string        
    Path      string        
    Main      Module        
    Deps      []*Module     
    Settings  []BuildSetting 
}

https://go.dev/issue/69712


goコマンドは、構文を使用してモジュールパスを解決する際に、リポジトリのサブディレクトリをモジュールルートのパスとして使用できるようになりました。これにより、root-pathがバージョン管理システムvcsを持つrepo-urlsubdirに対応することを示します。
特に単一のリポジトリ内で複数のGoモジュールを管理し、それぞれに異なるカスタムインポートパスを割り当てることが可能になるため、マイクロサービスアーキテクチャやモノレポ構成において有用です。

meta go-importの設定方法

meta go-importタグは、カスタムインポートパスを設定するためのHTMLのmetaタグで、Webサーバーのレスポンスのセクションに記載します。

DOCTYPE html>
html>
head>
    meta name="go-import" content="example.com/mymodule git https://github.com/user/mymodule">
head>
body>
    p>Go to a href="https://github.com/user/mymodule">GitHub repositorya>p>
body>
html>

動作

  1. ユーザーがgo get example.com/mymoduleを実行
  2. Goコマンドがhttps://example.com/mymodule?go-get=1にHTTPリクエストを送信
  3. サーバーがmetaタグを含むHTMLを返却
  4. Goコマンドがmetaタグの情報を使って実際のリポジトリからコードを取得

https://go.dev/issue/34055


新しいworkパッケージパターンは、work(以前はmainと呼ばれていた)モジュール内のすべてのパッケージにマッチします。

使用例


go build work


go test work


go vet work

モジュールモードとワークスペースモードでの挙動の違い

https://go.dev/issue/71294


goコマンドがgo.modまたはgo.workファイルのgoディレクティブを更新する際、コマンドの現在のバージョンを指定するtoolchainディレクティブを追加しなくなりました。

https://go.dev/issue/65847

vet

go vetコマンドに新しいアナライザが含まれます。

waitgroup: sync.WaitGroup.Addを不適切に使用している場合に検出されます。

問題のあるコード

var wg sync.WaitGroup
for i := 0; i  5; i++ {
    go func() {
        wg.Add(1)        
        defer wg.Done()
        
    }()
}
wg.Wait() 

正しいコード

var wg sync.WaitGroup
for i := 0; i  5; i++ {
    wg.Add(1)           
    go func() {
        defer wg.Done()
        
    }()
}
wg.Wait() 

https://go.dev/issue/18022

hostport: fmt.Sprintf("%s:%d", host, port)の形式でnet.Dial用アドレスを構築している場合に、net.JoinHostPortを代わりに提案します。これは前者がIPv6アドレスを扱う際に、省略記法により意図しない表記をしてしまう可能性があるためです。


addr := fmt.Sprintf("%s:%d", host, port)


addr := net.JoinHostPort(host, strconv.Itoa(port))

https://go.dev/issue/28308

runtime

GOMAXPROCSのデフォルト動作が変更されました。Goの以前のバージョンでは、GOMAXPROCSは起動時に利用可能な論理CPU数(runtime.NumCPU)がデフォルトで設定されていました。Go1.25では2つの変更点が追加されています。

  1. Linuxでは、ランタイムはプロセスを含むcgroupのCPU帯域幅制限を考慮します。CPU帯域幅制限によるCPU数が論理CPU数より低い場合、GOMAXPROCSはより低い値に設定されます。Kubernetesなどのコンテナランタイムシステムでは、cgroupのCPU帯域幅制限は一般的に「CPU limit」オプションに対応します。「CPU requests」オプションは考慮しません。

  2. すべてのOSで、論理CPU数やcgroupのCPU帯域幅制限が変更された場合、ランタイムは定期的にGOMAXPROCSを更新します。

これらの動作は両方とも、GOMAXPROCS環境変数またはruntime.GOMAXPROCSによって手動でGOMAXPROCSが設定されている場合、自動的に無効になります。GODEBUGの設定 containermaxprocs=0updatemaxprocs=0でそれぞれ明示的に無効にすることもできます。

更新されたcgroup制限の読み取りをサポートするため、ランタイムはプロセスの存続期間中、cgroupファイル用にキャッシュされたファイルディスクリプタを保持します。

詳しくは公式ブログをご参照ください。

https://go.dev/blog/container-aware-gomaxprocs

https://go.dev/issue/73193


既存のガベージコレクタの一部を置き換える新しいガベージコレクタが実験的に利用できるようになりました。このガベージコレクタの設計は、より良い局所性とCPUスケーラビリティを通じて小さなオブジェクトのマーキングとスキャンの性能を向上させます。ベンチマーク結果は様々ですが、ガベージコレクションを頻繁に実行する実際的なプログラムでは、ガベージコレクションのオーバーヘッドが10〜40%程度削減される見込みです。

新しいガベージコレクタは、ビルド時にGOEXPERIMENT=greenteagcを設定して有効化できます。

ちなみに新しいガベージコレクタはGreen Teaと呼ばれていて、命名の由来はメインで実装したAustin Clements氏が、日本滞在中に毎日抹茶を飲みながらアルゴリズム開発の進捗を多く生めたからだそうです。

https://changelog.com/gotime/333#transcript-39

上記のGo Timeやプロポーザルでも言及されていますが、SIMDの活用などまだまだ改善する余地があるとのことで、今後さらにパフォーマンスの改善が期待できそうです。

https://go.dev/issue/73581


ランタイムの実行トレースは長い間、アプリケーションの低レベル動作を理解し、デバッグするための強力で負荷の高い手段を提供してきました。しかしながら、実行トレースを継続的にファイルに書き込むコストとそのサイズのため、一般的に稀にしか発生しないイベントのデバッグでは実用的ではありませんでした。

新しいruntime/trace.FlightRecorderは、トレースをメモリ内のリングバッファに継続的に記録することで、ランタイムの実行トレースをキャプチャする軽量な手段を提供します。重要なイベントが発生した際、プログラムはFlightRecorder.WriteToを呼び出し、過去数秒間のトレースをファイルに書き込むことができます。

FlightRecorderによってキャプチャされる時間の長さとデータ量は、FlightRecorderConfig内で設定できます。

使用例


recorder := trace.NewFlightRecorder(
    trace.FlightRecorderConfig{
        MinAge: 5 * time.Second, 
        MaxBytes: 0,             
    },
)
recorder.Start()
defer recorder.Stop()


file, _ := os.Create("trace.out")
recorder.WriteTo(file)

https://go.dev/issue/63185


panicをrecover後に再びpanicが発生し、recoverしないままプログラムが終了する場合に出力されるメッセージは、出力する値が同じであれば繰り返し表示されなくなりました。

Go1.25以前は以下のように出力していました。

    panic: PANIC [recovered]
      panic: PANIC

Go1.25からは以下のようにされます。

    panic: PANIC [recovered, repanicked]

出力する値が異なれば従来通りのメッセージが出力されます。

    panic: PANIC1 [recovered]
      panic: PANIC2

https://go.dev/issue/71517


匿名仮想メモリ領域(VMA: Virtual Memory Area)名のカーネルサポート(CONFIG_ANON_VMA_NAME)があるLinuxでは、Goランタイムは匿名メモリマッピングにその目的に関する情報を付加するようになります。例えば、ヒープメモリに対して[anon: Go: heap]のような具合です。これはGODEBUGの設定 decoratemappings=0で無効にできます。

匿名VMAとは

  • 匿名メモリ: 特定のファイルに結び付いていないメモリ領域(プログラムが動的に割り当てるメモリ)
  • VMA: Linuxカーネルがメモリ領域を管理する単位

before/after

  • before: /proc/[pid]/mapsで表示される際、用途が不明で「[anon]」とのみ表示
  • after: 「[anon: Go: heap]」「[anon: Go: stack]」などのコンテキストに即した情報を付与

https://go.dev/issue/71546

compiler

Go1.25で、Go 1.21で混入したバグが修正されました。このバグはnilポインタチェックを不正に遅延させる可能性がありました。以下のように(不正に)正常に実行されていたプログラムは、今後(正しく)nilポインタ例外でパニックします。

package main

import "os"

func main() {
	f, err := os.Open("nonExistentFile")
	name := f.Name()
	if err != nil {
		return
	}
	println(name)
}

このプログラムは、エラーをチェックする前にos.Openの結果を使用しているため正しくありません。errがnon-nilの場合fの結果はnilであり、その場合f.Name()は内部でf.nameとnilのフィールドを参照しているのでパニックすべきです。しかし、Go 1.21から1.24では、コンパイラはnilチェックをエラーチェックまで不正に遅延させ、プログラムが正常に実行されていました。これはGoの仕様に違反しています。Go1.25では正常に実行されません。(ちなみにf.Name()が呼ばれた時点でpanicはしないのは仕様通りです)

https://go.dev/issue/72860

※リリースノートのサンプルコードだと分かりずらいので補足
以下のコードをGo1.25以前で実行した場合、panicにならずに③を出力してプログラムが正常終了します。そしてGo1.25以前のバージョンのまま②or④のコメントアウトを外して実行すると、①でpanicとなります。Go1.25以降で実行した場合は②or④のコメントアウトを外さずとも①でpanicするようになります。

package main

import (
	"fmt"
)

func main() {
	m := map[string]*struct {
		field int
	}{}
	t, ok := m[""]

	valid := t.field > 0 

	

	if !ok || !valid {
		fmt.Printf("got: %v\n", t) 
	}

	
}

https://go.dev/issue/72860


Go1.25のコンパイラとリンカは、DWARFバージョン5を使用してデバッグ情報を生成するようになりました。新しいDWARFバージョンは、Goバイナリのデバッグ情報に必要なメモリを削減し、特に大きなGoバイナリに対してリンク時間を短縮します。

デバッガへの影響

  • 起動の高速化: デバッグ情報のサイズ削減により、起動時間が短縮される可能性
  • メモリ使用量の削減: デバッガがロードするデバッグ情報が少なくなるため、メモリ効率が向上

https://go.dev/issue/26379


コンパイラは、より多くの状況でスライスのバッキングストア(スライスを構成するarray, len, capといった情報)をスタックに割り当てることができるようになり、性能が向上しました。この変更は、不適切にunsafe.Pointerを使用した場合、影響する可能性があります。例としてissue73199を参照してください。これらの問題を追跡するために、bisectツール-compile=variablemakeフラグと組み合わせて使用して、問題の原因となる割り当てを見つけることができます。このような新しいスタック割り当ては-gcflags=all=-d=variablemakehash=nを使用してオフにすることもできます。

linker

リンカは-funcalign=Nコマンドラインオプションを受け入れるようになりました。これは関数エントリのアライメントを指定します。
デフォルト値はプラットフォーム依存であり、このリリースでは変更されていません。

new packages

testing/synctest

testing/synctestパッケージは、並行処理を行うコードのテストをサポートします。

Test関数は、隔離されたスコープである「バブル」内でテスト関数を実行します。バブル内では、時間は仮想化されます。timeパッケージの処理は疑似クロックで動作し、バブル内のすべてのgoroutineがブロックされている場合、クロックは瞬時に進みます。

Wait関数は、現在のバブル内のすべてのgoroutineがブロックされるまで待ちます。

https://go.dev/issue/67434

https://go.dev/issue/73567

encoding/json/v2

Go1.25では、ビルド時に環境変数GOEXPERIMENT=jsonv2を有効にすることで、JSONの新しい実装を使用できます。

有効にした場合、2つの新しいパッケージが利用可能になります。

  • encoding/json/v2パッケージは、encoding/jsonパッケージの代替です

    • より良い性能: Marshal/Unmarshal処理の大幅な高速化
    • メモリ効率: ガベージコレクションの負荷を軽減する設計
    • ストリーミングサポート: 大きなJSONデータのストリーム処理
    • 型安全性の向上: より厳密な型チェックとエラーハンドリング
    • カスタマイゼーション: フィールドの命名規則やフォーマットの細かい制御
    • 互換性の改善: 様々なJSONバリアントとの相互運用性
    • エラー情報の詳細化: デバッグしやすいエラーメッセージ
  • encoding/json/jsontextパッケージは、JSON構文の低レベル処理を提供します

    • ストリーミングJSON読み取り・書き込みAPIを提供
    • トークンレベルでのJSON解析と生成が可能
    • メモリ効率的なJSON処理を実現
    • カスタムJSONフォーマットの実装をサポート
    • 既存のencoding/jsonパッケージの基盤として機能

さらに、jsonv2が有効な場合、

  • encoding/jsonパッケージは内部でencoding/json/v2を使用します。MarshallingとUnmarshallingの動作は影響を受けませんが、パッケージ関数によって返されるエラーのテキストが変更される可能性があります
  • encoding/json/v2パッケージには、MarshallerとUnmarshallerを実装する際に使用できる多くのオプションstruct tagが追加されます

v2では多くのシナリオでv1よりも大幅に優れた性能を発揮します。基本的に、Marshalの性能は同等であり、Unmarshalはv2で大幅な高速化を見込めます。より詳細な分析については、github.com/go-json-experiment/jsonbenchリポジトリを参照してください。

詳細についてはプロポーザルパッケージのコメントをご参照ください。

v1からv2へのマイグレーションについてはMigrating to v2を参照してください。

minor changes to packages

archive/tar

Writer.AddFSメソッドは、io/fs.ReadLinkFSを実装するfs.FSでシンボリックリンクをサポートするようになりました。

encoding/asn1

UnmarshalUnmarshalWithParamsは、ASN.1タイプのT61StringとBMPStringをより一貫して解析するようになりました。これにより、以前受け入れられていた一部の不正な形式のエンコードが拒否される可能性があります。

crypto

MessageSignerは、署名するメッセージを自分でハッシュ化できる新しい署名インターフェースです。新しい関数SignMessageも導入され、SignerインターフェースをMessageSignerにアップグレードしようと試み、成功した場合はMessageSigner.SignMessageメソッドを使用し、そうでなければSigner.Signを使用します。これは、SignerMessageSignerの両方をサポートしたいコードで使用できます。


プログラム開始後にGODEBUG設定fips140を変更しても何も起きなくなりました。以前は許可されていないと文書化されており、変更された場合にパニックを引き起こす可能性がありました。


SHA-1、SHA-256、SHA-512は、AVX2命令が利用できない場合、amd64でより遅くなりました。2015年以降に製造されたほとんどすべてのプロセッサはAVX2をサポートしています。

crypto/ecdsa

新しいParseRawPrivateKeyParseUncompressedPublicKeyPrivateKey.BytesPublicKey.Bytes関数とメソッドは、低レベルのエンコーディングを実装し、crypto/ellipticmath/big関数とメソッドを駆使しなくてよくなりました。

従来の実装との比較

従来、ECDSAキーの生のバイト形式との変換には、楕円曲線の数学的操作や大きな整数の処理が必要でした。


func privateKeyToBytes(priv *ecdsa.PrivateKey) []byte {
    
    return priv.D.Bytes()
}

func publicKeyToBytes(pub *ecdsa.PublicKey) []byte {
    
    x := pub.X.Bytes()
    y := pub.Y.Bytes()
    
    uncompressed := make([]byte, 1+len(x)+len(y))
    uncompressed[0] = 0x04 
    copy(uncompressed[1:], x)
    copy(uncompressed[1+len(x):], y)
    return uncompressed
}

func privateKeyToBytes(priv *ecdsa.PrivateKey) []byte {
    return priv.Bytes() 
}

func publicKeyToBytes(pub *ecdsa.PublicKey) []byte {
    return pub.Bytes() 
}


func bytesToKeys(privBytes, pubBytes []byte) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) {
    priv, err := ecdsa.ParseRawPrivateKey(privBytes)
    if err != nil {
        return nil, nil, err
    }
    
    pub, err := ecdsa.ParseUncompressedPublicKey(pubBytes)
    if err != nil {
        return nil, nil, err
    }
    
    return priv, pub, nil
}

この変更により、開発者は楕円曲線暗号の数学的詳細を理解することなく、ECDSAキーの生のバイト表現を安全かつ効率的に処理できるようになります。


FIPS 140-3モードが有効な場合、署名は4倍高速になり、非FIPSモードの性能と一致します。

crypto/ed25519

FIPS 140-3モードが有効な場合、署名は4倍高速になり、非FIPSモードの性能と一致します。

crypto/elliptic

Curveインターフェースの実装の一部で文書化されていないInverseCombinedMultメソッドが実装されていましたが削除されました。

crypto/rsa

PublicKeyは、modulus値が秘匿されているとは言えなくなりました。VerifyPKCS1v15VerifyPSSは、すべての入力が公開されリークする可能性があることをすでに警告しており、他の公開値からmodulusを復元できる数学的攻撃が存在します。


鍵生成は3倍高速になりました。

crypto/sha1

SHA-NI命令が利用可能な場合、amd64でハッシュ化が2倍高速になりました。

crypto/sha3

新しいSHA3.Cloneメソッドはhash.Clonerを実装します。


Apple M系プロセッサでハッシュ化が2倍高速になりました。

crypto/tls

新しいConnectionState.CurveIDフィールドは、接続を確立するために使用された鍵交換メカニズムを公開します。


新しいConfig.GetEncryptedClientHelloKeysコールバックは、クライアントがEncrypted Client Hello拡張を送信する際にサーバーが使用するEncryptedClientHelloKeyを設定するために使用できます。


RFC 9155に従い、SHA-1署名アルゴリズムはTLS 1.2ハンドシェイクで許可されなくなりました。
これらはGODEBUGの設定tlssha1=1で再び有効化できます。


FIPS 140-3モードが有効な場合、TLS 1.2でExtended Master Secretが必要になり、Ed25519とX25519MLKEM768が許可されるようになりました。


TLSサーバーは、クライアントの最も優先されるプロトコルバージョンでなくても、最高のサポートされるプロトコルバージョンを優先するようになりました。


TLSクライアントとサーバーの両方が、仕様に従うことと仕様外の動作を拒否することにおいて、より厳格になりました。準拠するピアとの接続は影響を受けないはずです。

crypto/x509

CreateCertificateCreateCertificateRequestCreateRevocationListは、crypto.Signerだけでなくcrypto.MessageSigner署名インターフェースも受け入れることができるようになりました。これにより、これらの関数は、呼び出し元によってではなく署名操作の一部としてハッシュが行われる「ワンショット」署名インターフェースを実装する型を使用することができます。


CreateCertificateは、SubjectKeyIdが不足している場合、切り詰められたSHA-256を使用してそれを設定するようになりました。
GODEBUGの設定x509sha256skid=0でSHA-1に戻します。


ParseCertificateは、負のpathLenConstraintを含むBasicConstraints拡張を含む証明書を拒否するようになりました。


ParseCertificateは、ASN.1 T61StringとBMPString型でエンコードされた文字列をより一貫して処理するようになりました。これにより、以前受け入れられていた一部の不正な形式のエンコーディングが拒否される可能性があります。

debug/elf

debug/elfパッケージはRISC-V ELF解析用の2つの新しい定数を追加します。

go/ast

FilterPackagePackageExportsMergePackageFiles関数、およびMergeMode型とその定数は、長期間非推奨のObjectPackage機構でのみ使用されているため、すべて非推奨となります。


新しいPreorderStack関数は、Inspectと同様に構文木を巡回し、サブツリーへの降下を制御しますが、便宜上、ノードの各ポイント以下のスタックも提供します。

go/parser

ParseDir関数は非推奨になります。

go/token

新しいFileSet.AddExistingFilesメソッドは、既存のFileFileSetに追加することを可能にし、または任意のFileセットに対してFileSetを構築することを可能にし、長時間実行されるアプリケーションで単一のグローバルFileSetに関連する問題を軽減します。

go/types

Varは、変数を以下のいずれかとして分類するVar.Kindメソッドを持つようになりました:パッケージレベル変数、レシーバ変数、引数、戻り値、ローカル変数、または構造体フィールド。

新しいLookupSelection関数は、既存のLookupFieldOrMethod関数と同様に、指定された名前とレシーバ型のフィールドまたはメソッドを検索しますが、結果をSelectionの形式で返します。

hash

新しいXOFインターフェースは、SHAKEなどの任意または無制限の出力長を持つハッシュ関数である「拡張可能出力関数」によって実装できます。

新しいClonerインターフェースを実装するハッシュは、その状態のコピーを返すことができます。すべてのHashの実装は現在Clonerを実装しています。

hash/maphash

新しいHash.Cloneメソッドはhash.Clonerを実装します。

io/fs

新しいReadLinkFSインターフェースは、ファイルシステム内のシンボリックリンクを読み取る能力を提供します。

log/slog

GroupAttrsAttr値のスライスからグループAttrを作成します。

Recordは、ソース位置を返すか、利用できない場合はnilを返すSourceメソッドを持つようになりました。

mime/multipart

新しいヘルパー関数FileContentDispositionは、マルチパートContent-Dispositionヘッダーフィールドを構築します。

net

LookupMXResolver.LookupMXは、有効なIPアドレスのように見えるDNS名と有効なドメイン名を返すようになりました。

具体的な変更内容

Go1.24以前では、MXレコードの値として192.168.1.100のようなIPアドレスが返された場合、RFC 5321の厳密な要求に従ってこれらの値は破棄されていました。しかし、実際の運用環境では、一部のネームサーバーや設定でMXレコードにIPアドレスが設定されることがあります。

返される値の例


mx, err := net.LookupMX("example.com")
if err != nil {
    log.Fatal(err)
}

for _, record := range mx {
    fmt.Printf("Priority: %d, Host: %s\n", record.Pref, record.Host)
}




この変更により、RFC要求よりも実用性を重視し、実際のインフラで動作しているメールシステムとの互換性が向上します。


WindowsでLookupMXは、ListenMulticastUDPがIPv6アドレスをサポートするようになりました。


Windowsでは、os.Fileとネットワーク接続間の変換が可能になりました。具体的には、FileConnFilePacketConnFileListener関数が実装され、開いているファイルに対応するネットワーク接続またはリスナーを返します。
同様に、TCPConnUDPConnUnixConnIPConnTCPListenerUnixListenerFileメソッドが実装され、ネットワーク接続の基礎となるos.Fileを返します。

net/http

新しいCrossOriginProtectionは、安全でないクロスオリジンブラウザのリクエストを拒否することにより、Cross-Site Request Forgery(CSRF)に対する保護を実装します。
これはモダンブラウザのFetchメタデータを使用し、トークンやクッキーを必要とせず、オリジンベースとパターンベースのバイパスをサポートします。

使用例

package main

import (
    "fmt"
    "net/http"
)

func main() {
    
    
    protection := http.CrossOriginProtection{}
    http.Handle("/api/", protection.Wrap(http.HandlerFunc(apiHandler)))
    
    
    
    protectionWithAllowlist := http.CrossOriginProtection{
        AllowedOrigins: []string{
            "https://trusted-app.example.com",
            "https://*.internal.company.com", 
        },
    }
    http.Handle("/admin/", protectionWithAllowlist.Wrap(http.HandlerFunc(adminHandler)))
    
    
    devProtection := http.CrossOriginProtection{
        AllowedOrigins: []string{
            "http://localhost:*", 
        },
    }
    http.Handle("/dev-api/", devProtection.Wrap(http.HandlerFunc(devHandler)))
    
    http.ListenAndServe(":8080", nil)
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Secure API endpoint accessed safely")
}

func adminHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Admin function executed")
}

func devHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Development API")
}

動作の仕組み

  1. 自動判定: ブラウザが送信するSec-Fetch-Siteヘッダーを確認

    • same-origin: 同一オリジンからのリクエスト → 許可
    • cross-site: クロスサイトリクエスト → 検証または拒否
    • none: 直接アクセス(ブックマークなど) → 許可
  2. 設定不要: 従来のCSRFトークンやクッキーの設定が不要
  3. 柔軟な制御: 必要に応じて特定のオリジンを許可リストに追加可能

この機能により、モダンなブラウザでのCSRF攻撃を簡単かつ効果的に防ぐことができます。

os

Windowsでは、NewFileが非同期I/O用に開かれたハンドルをサポートするようになりました(つまり、syscall.CreateFile呼び出しでsyscall.FILE_FLAG_OVERLAPPEDが指定されている)。
これらのハンドルはGoランタイムのI/O完了ポートに関連付けられ、結果として得られるFileに以下の利点を提供します。

この機能強化は、Windowsで名前付きパイプを介して通信するアプリケーションに特に有益です。

ハンドルは一度に1つの完了ポートにのみ関連付けることができることに注意してください。
NewFileに提供されたハンドルがすでに完了ポートに関連付けられている場合、返されるFileは同期I/Oモードにダウングレードされます。
この場合、I/OメソッドはOSスレッドをブロックし、デッドラインメソッドは効果がありません。


DirFSRoot.FSによって返されるfs.FSは、新しいio/fs.ReadLinkFSインターフェースを実装します。
CopyFSは、io/fs.ReadLinkFSを実装するfs.FSをコピーする際にシンボリックリンクをサポートします。


Root型は以下の追加メソッドをサポートします。

https://go.dev/issue/73126

reflect

新しいTypeAssert関数は、Valueを指定された型のGoの値に直接変換することを許容します。これはValue.Interfaceの結果に型アサーションを使用するのと似ていますが、不要なメモリ割り当てを避けます。

regexp/syntax

\p{name}\P{name}文字クラス構文(Unicode文字クラスエスケープ)は、Any、ASCII、Assigned、Cn、LC、および\p{Letter}\pL用)などのUnicodeカテゴリエイリアスの名前を受け入れるようになりました。
Unicode TR18に従い、スペース、アンダースコア、ハイフンを無視して、大文字小文字を区別しない名前検索も使用するようになりました。

https://github.com/golang/go/issues/70781

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape

runtime

AddCleanupによってスケジュールされたクリーンアップ関数は、並行・並列に実行されるようになり、uniqueパッケージのように過度にしようする場合でも効率的に実行可能になりました。個々のクリーンアップ処理が長時間実行またはブロックされて、クリーンアップキューのブロックが発生するのを避けるために、その処理は新しいgoroutineに移されるようになるはずです。


新しいGODEBUG=checkfinalizers=1設定は、GCガイドで説明されているようなファイナライザーとクリーンアップの一般的な問題を検出するのに役立ちます。
このモードでは、ランタイムは各ガベージコレクションサイクルで診断を行い、長時間実行される問題のあるファイナライザーやクリーンアップを特定するのに役立つよう、ファイナライザーとクリーンアップキューの長さをstderrに定期的に出力します。
詳細については、GODEBUGドキュメントを参照してください。


新しいSetDefaultGOMAXPROCS関数は、GOMAXPROCSが設定されていない場合のデフォルト値を設定します。

runtime/pprof

ランタイム内部のロックの競合に関するmutexプロファイルは、遅延を引き起こしたクリティカルセクションの終了を正しく指すようになりました。これはsync.Mutexの競合に対するプロファイルの動作と一致します。

sync

新しいWaitGroup.Goメソッドは、複数のgoroutineを作成してそれらの終了を待つ一般的なパターンをより便利にします。

Go1.24以前の従来の方法

func processItems(items []string) {
    var wg sync.WaitGroup
    
    for _, item := range items {
        wg.Add(1)           
        go func(item string) {
            defer wg.Done() 
            process(item)
        }(item)
    }
    
    wg.Wait()
}

Go1.25の新しい方法

func processItems(items []string) {
    var wg sync.WaitGroup
    
    for _, item := range items {
        wg.Go(func() { 
            process(item)
        })
    }
    
    wg.Wait()
}

testing

新しいメソッドT.AttrB.AttrF.Attrは、テストログに属性を出力します。属性は、テストに関連付けられた任意のkey-valueです。

例えば、TestFという名前のテストで、t.Attr("key", "value")の出力は以下のようになります。

-jsonフラグを使用すると、属性は新しい「attr」アクションとして出力されます。


TBFの新しいOutputメソッドは、TB.Logと同様にテストの出力に書き込めるio.Writerを提供します。
TB.Logと同様に、出力はインデントされますが、ファイル名と行番号は含まれません。

https://go.dev/issue/59928


AllocsPerRun関数は、並列テストが実行されている場合にパニックするようになりました。
AllocsPerRunの結果は、他のテストが実行されている場合、本質的に不安定です。
新しいパニック動作は、このようなバグを検知するのに役立ちます。

https://go.dev/issue/70464

testing/fstest

MapFSio/fs.ReadLinkFSインターフェースを実装します。
TestFSは、io/fs.ReadLinkFSインターフェースを実装している場合、Lstatの値を見るようになります。
TestFSは、無限に再帰することを避けるためにシンボリックリンクを追跡しなくなりました。

unicode

新しいCategoryAliasesマップは、「L」に対する「Letter」などのカテゴリエイリアス名への変換手段を提供します。

新しいカテゴリCnLCは、それぞれ未割り当てのコードポイントと大文字小文字のある文字を定義します。
これらは常にUnicodeによって定義されていましたが、Go1.25以前では誤って省略されていました。
Cカテゴリは現在Cnを含むため、すべての未割り当てのコードポイントが追加されています。

https://github.com/golang/go/issues/70780

https://developer.mozilla.org/en-US/docs/Glossary/Code_point

unique

uniqueパッケージは、インターン化された値をより積極的に、効率的に、並列に回収するようになりました。その結果、Make関数を使用するアプリケーションは、ユニークな値が多数インターン化された場合に、メモリ使用量の急激な増加が起きにくくなりました。

Handleを含むMake関数に渡された値は、ガベージコレクションでの回収時に、値の階層の深さに比例したサイクル数を要していました。Go1.25からは、未使用になると、1回のサイクルですぐに回収されます。

ports

Darwin

Go1.24のリリースノートに書かれていた通り、Go1.25はmacOS 12 Monterey以降をサポート対象とします。

https://go.dev/issue/69839

Windows

Go1.25は、不具合のある 32ビットwindows/armポート(GOOS=windows GOARCH=arm)を含む最後のリリースです。Go1.26で削除される予定です。

https://go.dev/issue/71671

Loong64

linux/loong64ポートは、race detector、runtime.SetCgoTracebackを使用したCコードからのトレースバック情報の収集、および内部リンクモードでのcgoプログラムのリンクをサポートするようになりました。

RISC-V

linux/riscv64ポートでpluginビルドモードをサポートするようになりました。

https://go-review.googlesource.com/c/go/+/420114


GORISCV64環境変数に新しい値rva23u64を設定することで、RVA23U64プロファイルの命令セットを利用できるようになります。

https://go.dev/issue/61476



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -