2015-12-18 5 views
6

Я только начинаю с GoLang, и я смотрю одно из своих учебников (https://golang.org/doc/code.html).Structs in GoLang

В одном из своих примеров они устанавливают переменную в структуру, но я настолько смущен тем, как они обращаются к элементам структуры в цикле for ниже? Есть ли шанс, что кто-то может уточнить? Большое спасибо!

Код:

package stringutil 

import "testing" 

func TestReverse(t *testing.T) { 
    cases := []struct { 
     in, want string 
    }{ 
     {"Hello, world", "dlrow ,olleH"}, 
     {"Hello, 世界", "界世 ,olleH"}, 
     {"", ""}, 
    } 
    for _, c := range cases { 
     got := Reverse(c.in) 
     if got != c.want { 
      t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) 
     } 
    } 
} 
+0

Они не установив переменную на структуру, они установив его ломтиком структур. –

ответ

7

Ниже приведен код, с некоторыми комментариями, чтобы помочь прояснить каждую роль утверждения в этом сообщении.

import "testing" 

func TestReverse(t *testing.T) { 
    cases := []struct { // declaration of anonymous type 
     in, want string // fields on that type called in and want, both strings 
    }{ 
     {"Hello, world", "dlrow ,olleH"}, 
     {"Hello, 世界", "界世 ,olleH"}, 
     {"", ""}, 
    } // composite literal initilization 
    // note the use of := in assigning to cases, that op combines declaration and assignment into one statement 
    for _, c := range cases { // range over cases, ignoring the index - the underscore means to discard that return value 
     got := Reverse(c.in) // c is the current instance, access in with the familiar dot notation 
     if got != c.want { // again, access operator on c, the current instance 
      t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) // more access 
     } 
    } 
} 

Дайте мне знать, если это поможет. Я могу попытаться дать больше резюме на разговорном языке или добавить дополнительные сведения, если некоторые из заявлений не имеют смысла. Кроме того, fyi, если вы не знакомы диапазонам диапазонов по коллекции, возвращаете k, v, где k является индексом или ключом и v значением.

EDIT: подробности о декларировании/initilization из cases

cases := []struct { 
     in, want string 
    } 

Этот бит внутри первой пары фигурных скобок является определение структуры. Это анонимный тип, нормальное объявление будет выглядеть так:

type case strcut { 
     in string 
     want string 
    } 

Если что-то подобное, то было бы тип называется case в рамках этого пакета (не экспортируются, если вы хотите, чтобы сделать это «общественность», так что необходимо будет type Case вместо этого). Вместо этого примеры struct являются анонимными. Он работает так же, как и обычный тип, однако, как разработчик, вы не сможете ссылаться на этот тип, чтобы вы могли практически работать с инициализацией коллекции. Внутренне этот тип такой же, как и любая другая структура с двумя невыложенными строками для полей. Поля называются in и want. Обратите внимание, что в задании cases := []struct у вас есть [] до struct, это означает, что вы объявляете кусочек этого анонимного типа.

Этот следующий бит называется статической инициализацией. Это синтаксис для инициализации коллекций типами. Каждый из этих вложенных битов, как {"", ""}, является объявлением и инициализацией одной из этих анонимных структур, обозначаемой снова фигурными фигурными фигурными скобками. В этом случае вы назначаете две пустые строки in и want соответственно (если вы не используете имена, порядок будет таким же, как в определении). Внешняя пара фигурных скобок предназначена для среза. Если ваш фрагмент был произнесён ints или strings, тогда вы просто получили бы значения прямо без дополнительного уровня вложенности, например myInts := []int{5,6,7}.

{ 
     {"Hello, world", "dlrow ,olleH"}, 
     {"Hello, 世界", "界世 ,olleH"}, 
     {"", ""}, 
    } 
+0

Как код может получить доступ к строкам в структуре через c.in и c.out? – thegreenfrog

+1

@thegreenfrog цикл повторяет фрагмент структур, их 3. Каждая из этих строк '{" Hello, world "," dlrow, olleH "}' создает экземпляр. 'for _, c: = range cases' является более или менее циклом foreach, который я бы прочитал как« для каждого случая 'c' в' cases'. '.' обычно называется оператором доступа (не уверен, что Go имеет определенное имя, отличное от этого), вы используете его для доступа к свойствам структуры. Если у меня есть какая-то структура 'A' ​​с некоторыми полями' One', 'Two' и' Three', я получаю доступ к этим полям из экземпляра типа 'A', вызывающего его' a' как 'a.One',' a . Два', 'a.Three'. – evanmcdonnal

+0

Я могу расширить это в ответ, если вам нужно уточнить. Если использование оператора доступа вам не знакомо, я бы рекомендовал сделать некоторые общие чтения по объектно-ориентированному программированию, потому что он используется почти на каждом языке. – evanmcdonnal

1

Идти корень того, что является структурой.

вы объявляете свои переменные в нем, а затем вы можете использовать его в функции. Пример:

package main 

import (
    "fmt" 

) 

func main() { 
    Get() 

} 

func Get(){ 
    out := new(Var) 

    out.name = "james" 

    fmt.Println(out.name) 
} 
type Var struct { 
    name string 
} 
0

Вы можете узнать больше о Golang Struc

 
// GO language program with an example of Struc Type 

package main 

import (
"fmt" 
) 

func main() { 
    type Salary struct{ 
     Basic, HRA, TA float64  
    } 

    type Employee struct{ 
     FirstName, LastName, Email string 
     Age int 
     MonthlySalary []Salary 
    } 

    e := Employee{ 
     FirstName: "Mark", 
     LastName: "Jones", 
     Email: "[email protected]", 
     Age: 25, 
     MonthlySalary: []Salary{ 
      Salary{ 
       Basic:15000.00, 
       HRA:5000.00, 
       TA:2000.00, 
      }, 
      Salary{ 
       Basic:16000.00, 
       HRA:5000.00, 
       TA:2100.00, 
      }, 
      Salary{ 
       Basic:17000.00, 
       HRA:5000.00, 
       TA:2200.00, 
      }, 
     }, 
    } 
    fmt.Println(e.FirstName,e.LastName) 
    fmt.Println(e.Age) 
    fmt.Println(e.Email) 
    fmt.Println(e.MonthlySalary[0]) 
    fmt.Println(e.MonthlySalary[1]) 
    fmt.Println(e.MonthlySalary[2]) 
}