Go で「Foo」のスライスを「Bar」のスライスに変換できないのはなぜですか?

Susan Sarandon
リリース: 2024-10-26 10:03:02
オリジナル
125 人が閲覧しました

Why Can't I Convert a Slice of `Foo` to a Slice of `Bar` in Go?

Go がスライス タイプの変換 (例: []Foo から []Bar) を許可しない理由

はじめに

Go では、型安全性と変換ルールのため、通常、1 つの値を別の型の変数に代入することは許可されません。お気づきのように、あるタイプの構造のスライス (例: []Foo) を別のタイプのスライス (例: []Bar) に変換することはできません。この記事は、Foo と Bar の基になる型が同一であるにもかかわらず、この変換が不可能な理由を明確にすることを目的としています。

変換ルール

Go 仕様による、非定数値 x は、次の基準のいずれかが満たされる場合にのみ型 T に変換できます:

  • x は T に代入可能です。
  • x および x の基になる型T は同一です。
  • x と T は、同じ基本型を持つ名前のないポインタ型です。
  • x と T は両方とも整数、浮動小数点、または複素数型です。
  • xは整数またはバイト/ルーンのスライスであり、T は文字列型です。
  • x は文字列で、T はバイト/ルーンのスライスです。

スライスの基礎となる型

スライスの基礎となる型は要素型へのポインタです。たとえば、[]Foo の基になる型は []Foo で、[]Bar の基になる型は []Bar です。 Foo の基になる型が Bar の基になる型と同じであっても、Foo と Bar のスライスの基になる型が同じになるわけではありません。

非変換の理由

したがって、基になる型が同じであっても、Go が異なる要素型のスライス間の変換を許可しない理由は、スライスの基になる型が同一ではないためです。その結果、[]Bar(foos) などの型変換は許可されません。

代替解決策

この問題に対する考えられる解決策の 1 つは、次のように定義することです。 Foo のスライスのカスタム タイプ エイリアス (Foos など)。これにより、次のコードに示すように、Foos のスライスから Bars のスライスを作成できます。

<code class="go">type Foo struct{ A int }
type Foos []Foo
type Bars Foos

func main() {
    foos := []Foo{Foo{1}, Foo{2}}
    bars := Bars(foos)

    fmt.Println(bars)
}</code>
ログイン後にコピー

この場合、Foos と Bars の基礎となる型は同一であり、変換は次のように機能します。

安全でないパッケージに関する考慮事項

Go は通常、安全でない操作を禁止していますが、安全でないパッケージを使用して変換制限を回避することは可能です。ただし、これは型安全性を損なう可能性があるため、潜在的な結果を理解し、注意して行う必要があります。

結論

変換ルールと基礎となるスライスの型を理解することは、 Go で型変換を処理するために重要です。異なる要素型のスライス間の直接変換は許可されていませんが、型の安全性を維持しながら必要な機能を実現するための、カスタム型エイリアスの定義などの代替ソリューションがあります。

以上がGo で「Foo」のスライスを「Bar」のスライスに変換できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!