Go 1.17 ではスライスを配列ポインタに変換できることに気づきましたか?

藏色散人
リリース: 2021-07-12 14:15:49
転載
2651 人が閲覧しました

今日は一日ですが週末です。 Go1.17 に関するちょっとしたニュースを共有させてください。毎日集魚スキルを身につけよう!

Go 言語では、スライスには、その配列が独立変数としてどこかに存在するか、スライスをサポートするために割り当てられた単なる配列であるかに関係なく、サポートする配列への参照が含まれます。

スライスの基本構造は次のとおりです。

// runtime/slice.go
type slice struct {
    array unsafe.Pointer // 指向底层数组的指针
    len   int // 长度 
    cap   int // 容量
}
ログイン後にコピー

配列をサポートする現在のスライス方法では、スライス中に興味深いメモリ リークが発生したり、スライスに驚くべき変更が発生したりする可能性があります。

もう 1 つの非常に重要な点は、Go 1.16 以前では、スライス型から配列型に変換する安全な方法がなく、非常に無力であるということです。

標準ライブラリのreflectまたはunsafeを呼び出して、安全でないコードを記述することによってのみこれを行うことができます:

(*[10]byte)(unsafe.Pointer(&b[0]))
ログイン後にコピー

これは明らかにエレガントではなく、公式自体も、処理が完了したら、 unsafe を使用することを推奨していません。問題が発生すると、比較的制御不可能な致命的なエラーが発生する可能性があります。

実際、Go がリリースされた直後 (Go 1.0 がリリースされるずっと前) 2009 年の時点で、一部の人々が関連する疑問を提起し、この問題の解決を望んでいた:

Go 1.17 ではスライスを配列ポインタに変換できることに気づきましたか?

最後に、今後の Go 1.17 では、仕様を更新するコミット ID #1c268431f4 で始まる一連の変更により、これが可能になります。

Go 1.17 ではスライスを配列ポインタに変換できることに気づきましたか?

新しい仕様でのこれの説明は非常に簡単です:

スライスを配列ポインターに変換すると、スライスの基になる配列へのポインターが生成されます。スライスの長さが配列の長さより短い場合、実行時パニックが発生します。
    スライスが配列の長さより長い場合は、無害であり、発生する可能性があります。普通に走ります。
  • スライスが配列より長い場合は、配列が元のスライスのサポートされているすべての配列にアクセスできないことを意味します。
さらに、仕様では、Go1.17 で使用できるいくつかの新しい例が提供されています。

s := make([]byte, 2, 4)
s0 := (*[0]byte)(s)      // s0 != nil
s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)

var t []string
t0 := (*[0]string)(t)    // t0 == nil
t1 := (*[1]string)(t)    // panics: len([1]string) > len(s)
ログイン後にコピー
    変数 s2 の変換: 基になる配列をスライスします。つまり、この変換では新しい配列が割り当てられない (割り当てられない) ため、効率が確保されます。
  • 変数 s0 と t0 の変換: 空ではないフラグメントを長さ 0 の配列に変換します。長さ 0 の配列では何もできませんが、有効なポインタ (nil) を与える必要があります。
現時点では、型アサーションなどの範囲外の理由によってパニック イベントが発生するかどうかを確認する方法がないことに注意してください。スニペットが短すぎてパニック イベントが発生する可能性があると思われる場合は、 if を使用して事前に判断する必要があります。

同時に、標準ライブラリの Reflect も更新され、スライスから配列ポインタへの変換をサポートします。Reflect を使用して関連する変換作業を実行している場合は、この提出の注記を読むことをお勧めします。

Go 言語での型変換に関するその他のアイデアや要望はありますか?

、あるいは落とし穴に遭遇したことはありますか? みなさんもコメント欄にメッセージを残してコミュニケーションをとっていただければ幸いです。

その他の golang 関連の技術記事については、

golang チュートリアル列をご覧ください。

以上がGo 1.17 ではスライスを配列ポインタに変換できることに気づきましたか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート