[移動]配列、文字列、およびスライス

配列、文字列とスライス

ゴー言語の配列、文字列、およびスライス3つのデータ構造が密接に関連しています。データのこれらの3つのタイプが、基礎となる生データメモリは、同じ構造を有しています。配列の要素を変更することができるが、アレイ自体は、質量参加および割り当ての機能であるが、プロセス全体をコピーする方法です。ストリング割り当ては、単に基礎となるデータの複製を引き起こすことなく、データ及び対応するアドレス長をコピーします。

配列

アレイは、固定長からなる特定のタイプの要素の配列であり、それはゼロ以上の要素のアレイから構成されてもよいです。配列の長さは、配列型の一部です。配列の長さは、配列型の部分であるので、異なる長さ又は異なるタイプのデータのアレイは、異なるタイプで構成され、従ってまれに、直接使用されない移動の配列(異なる長さの配列の異なるタイプを直接割り当てることができないため)。スライスの種類と配列の対応、スライスが動的に拡張および縮小、スライス機能をより柔軟に、しかし、事は配列スライスを理解することであるかを理解することができるシーケンスです。

定義された方法
var a [3]int // 定义长度为3的int型数组, 元素全部为0
var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2, 3
var c = [...]int{2: 3, 1: 2} // 定义长度为3的int型数组, 元素为 0, 2, 3
var d = [...]int{1, 2, 4: 5, 6} // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6

第一の方法は、基本的な配列変数を定義することで、明示的に指定された配列の長さは、配列の各要素は、ゼロ値に初期化されます。

アレイを定義する第二の方法は、初期設定値は時系列のすべての要素の定義で指定することができ、配列の長さは、自動的に要素の数に基づいて計算初期化されます。

第三の方法は、よりカジュアルな外観のために、インデックスアレイ状の要素、および要素の、したがって初期値を初期化することです。この初期化モードとマップ[int]は、初期化構文の似たタイプを入力します。配列インデックスの最大長は、0の値がまだ初期化されると初期化明確な要素が存在しない、優勢に見えます。

第4の実施形態は、初期化の第二及び第三の実施の形態の混合物であり、前方の最後の要素との最初の2つの要素を使用して、初期化シーケンス、ゼロの第三及び第四の初期値の一つの要素は、初期化要素のインデックスを介して第五、 5番目の要素を使用して、初期化シーケンスの後。

配列とポインタ

ゴー言語は、配列値のセマンティクスです。すなわち、配列変数は、それが(例えばCでアレイなど)暗黙点の最初の要素へのポインタが、完全な値ではなく、アレイ全体を表します。配列変数が割り当てられているか、配信される場合は、あなたが実際に配列全体をコピーします。アレイが大きければ、アレイの割り当ては、より大きなオーバーヘッドを有することになります。持参に配列をコピーするオーバーヘッドを回避するには、配列へのポインタを渡すことができますが、配列はポインタの配列ではありません。

var a = [...]int{1, 2, 3} // a 是一个数组
var b = &a // b 是指向数组的指针
fmt.Println(a[0], a[1]) // 打印数组的前2个元素
fmt.Println(b[0], b[1]) // 通过数组指针访问数组元素的方式和数组类似

本体構造のメンバの数が固定されているアレイは、特殊な構造、配列のインデックスに対応するフィールド名の構造とみなすことができます。lenが組み込み関数キャップ機能は、アレイの容量を計算するために使用することができる、配列の長さを計算するために使用されてもよいです。配列型、しかし、結果リターンLENとキャップの機能のために常に同一である、配列型の長さに対応しています。

トラバーサル
for i := range a {
    fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
    fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
    fmt.Printf("c[%d]: %d\n", i, c[i])
}

この反復配列の境界が表示されない状況を確保することができますので、良いかもしれレンジ性能のために反復的に使用して、判決が範囲外の添字の各反復を保存することができたときに、配列の要素にアクセスします。

文字列文字列は、典型的には、人間可読テキストデータを格納するために使用され、バイトの配列を変更することができません。配列が異なっていると、文字列の要素を変更することはできません、読み取りバイト配列です。各ストリングは、固定であるが、文字列型文字列の長さの一部ではないが。

reflect.StringHeaderでゴー下部構造定義言語の文字列:

type StringHeader struct {
    Data uintptr
    Len int
}

ストリング構造は、2つの情報から構成されていますバイトの基本配列に第1ストリング点、第2バイトは、文字列の長さです。

実際には、文字列が構造体であるので、文字列の割り当ては、プロセスreflect.StringHeader構造をコピーしています。

ではないが、文字列のセクションが、支持体スライス操作、メモリ・データ・アクセスのボトムの異なる位置(文字列が読み取り専用であるため、同一の文字列リテラルは、通常、同じ文字列定数に対応する)の切片。

s := "hello, world"
hello := s[:5]
world := s[7:]
s1 := "hello, world"[:5]
s2 := "hello, world"[7:]

スライス

構造定義スライス、reflect.SliceHeader:

type SliceHeader struct {
    Data uintptr
    Len int
    Cap int
}
定義された方法
var (
    a []int // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
    b = []int{} // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
    c = []int{1, 2, 3} // 有3个元素的切片, len和cap都为3
    d = c[:2] // 有2个元素的切片, len为2, cap为3
    e = c[0:2:cap(c)] // 有2个元素的切片, len为2, cap为3
    f = c[:0] // 有0个元素的切片, len为0, cap为3
    g = make([]int, 3) // 有3个元素的切片, len和cap都为3
    h = make([]int, 2, 3) // 有2个元素的切片, len为2, cap为3
    i = make([]int, 0, 3) // 有0个元素的切片, len为0, cap为3
)
トラバーサル
for i := range a {
    fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
    fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
    fmt.Printf("c[%d]: %d\n", i, c[i])
}

スライス自体または割り当てられた送信パラメータ、及び動作はポインタ配列と類似している場合、単にスライスヘッダ情報(reflect.SliceHeader)をコピーし、基礎となるデータがコピーされません。

加えます
var a []int
a = append(a, 1) // 追加1个元素
a = append(a, 1, 2, 3) // 追加多个元素, 手写解包方式
a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包

おすすめ

転載: www.cnblogs.com/Ryan16231112/p/12315363.html