2013-05-08 11 views
6

Jestem nowy w golangu, więc przepraszam, jeśli to pytanie jest zbyt naiwne. Rozejrzałem się, ale nie mogłem znaleźć odpowiedzi na moje podstawowe pytanie.Typ asercji rzutowania na betonowej strukturze?

Powiedzmy, że mam konkretną strukturę i metody, jak pokazano poniżej.

type MyData struct{ 
    field1 string 
    field2 int 
    } 

func(a MyData) OperatorOnString() string{ 
    return a.field1.(string) 
} 

func(a MyData) OperatorOnInt() int{ 
    return a.field2.(int) 
} 

Moje pytanie brzmi, czy mogę wpisać rzut i powrócić, zamiast wykonywać asercję? Z tego, czego się nauczyłem, wynika, że ​​asercja jest używana na danych typu interface. Ale w tym przypadku mam konkretny typ. Czy nadal powinienem używać twierdzenia lub mogę zrobić coś takiego, jak return int(a.field2). Wiem, że ten przykład jest banalny, ale chodzi o to, że jestem zdezorientowany, kiedy użyć między dwoma typami konwersji. A może chodzi tu o idiomatyczność golang?

Dzięki

Odpowiedz

9

Przede wszystkim type assertion mogą być wykorzystywane wyłącznie na interfejsach:

Dla wyrażenia x typu interfejsu i typu T, pierwotnej ekspresji

x.(T) 

zapewnia, że ​​x nie jest zerowe i wartość przechowywana w x jest typu T. Oznaczenie x.(T) nazywa się asercją typu.

Ale stosujesz go w polach bez interfejsu (int i string). To czyni kompilator unhappy.

Po drugie, jeśli chcesz zwrócić typ T z metody/funkcji, zawsze wystarczy zwrócić wyrażenie typu T, które już są twoje pola. Poprawny kod jest następnie proste:

package main 

import "fmt" 

type MyData struct { 
     field1 string 
     field2 int 
} 

func (a MyData) OperatorOnString() string { 
     return a.field1 
} 

func (a MyData) OperatorOnInt() int { 
     return a.field2 
} 

func main() { 
     a := MyData{"foo", 42} 
     fmt.Println(a.OperatorOnString(), a.OperatorOnInt()) 
} 

Playground


wyjściowa:

foo 42 
+0

Dzięki. Jednak w prawdziwym scenariuszu moi operatorzy będą mieli pewne argumenty, które będą używane do działania w polach MyData. Zatem przed zwróceniem tego pola, czy muszę sprawdzić typ? – Minty

+0

@Minty: Pokaż prawdziwy kod. Najprawdopodobniej mieszasz kilka pojęć i nie będzie lepiej bez prawdziwego kodu. – Volker

+1

@Minty: Jeśli fn zwróci typ 'T', wówczas tylko wyrażenia typu' T' mogą pojawić się w 'return expr'. Nie chodzi o pola, chodzi o rodzaj ekspresji. Na przykład. jeśli powiemy, że mamy 'var i int' w fn zwracającym' int64', wtedy możemy i musimy napisać 'return int64 (i)'. Ad ", aby sprawdzić typ": Sprawdzanie typu jest automatycznie wykonywane przez kompilator. – zzzz

Powiązane problemy