Tracks
/
Go
Go
/
Übungen
/
Sortierraum
Sortierraum

Sortierraum

Lernübung

Einführung

Typkonvertierung

Go erfordert eine explizite Konvertierung zwischen verschiedenen Typen. Die Konvertierung zwischen Typen (auch bekannt als Typumwandlung) erfolgt über eine Funktion mit dem Namen des Typs, in den konvertiert werden soll. Um zum Beispiel einen int in einen float64 umzuwandeln, gehst du wie folgt vor:

var x int = 42 // x has type int
f := float64(x) // f has type float64 (ie. 42.0)

Konvertierung zwischen primitiven Typen und Strings

Es gibt ein strconv-Paket für die Konvertierung zwischen primitiven Typen (wie int) und string.

import "strconv"

var intString string = "42"
var i, err = strconv.Atoi(intString)

var number int = 12
var s string = strconv.Itoa(number)

Typzusicherungen

Interfaces in Go können zu Mehrdeutigkeit hinsichtlich des zugrunde liegenden Typs führen. Eine Typzusicherung ermöglicht es uns, den zugrunde liegenden konkreten Wert des Interface-Werts mit dieser Syntax zu extrahieren: interfaceVariable.(concreteType).

Zum Beispiel:

var input any = 12
number := input.(int)

HINWEIS: Dies führt zu einer Panik, wenn die Interface-Variable keinen Wert des konkreten Typs enthält.

Wir können testen, ob ein Interface-Wert einen bestimmten konkreten Typ enthält, indem wir beide Rückgabewerte der Typzusicherung nutzen: den zugrunde liegenden Wert und einen booleschen Wert, der angibt, ob die Zusicherung erfolgreich war. Zum Beispiel:

str, ok := input.(string) // no panic if input is not a string

Wenn input einen string enthält, dann ist str der zugrunde liegende Wert und ok ist wahr. Wenn input keinen string enthält, dann ist str der Nullwert vom Typ string (d. h. "", der leere String) und ok ist falsch. In keinem Fall tritt eine Panik auf.

Typweichen

Eine Typweiche kann mehrere Typzusicherungen nacheinander ausführen. Sie hat dieselbe Syntax wie eine Typzusicherung (interfaceVariable.(concreteType)), aber der concreteType wird durch das Schlüsselwort type ersetzt. Hier ist ein Beispiel:

var i any = 12 // try: 12.3, true, int64(12), []int{}, map[string]int{}

switch v := i.(type) {
case int:
    fmt.Printf("the integer %d\n", v)
case string:
    fmt.Printf("the string %s\n", v)
default:
    fmt.Printf("type, %T, not handled explicitly: %#v\n", v, v)
}

Anleitung

Jen arbeitet im Sortierraum einer großen Fabrik. Der Sortierraum muss alles verarbeiten, was hereinkommt, indem er es kategorisiert und mit einem Etikett versieht. Jen ist für Dinge zuständig, die bereits als Zahlen vorkategorisiert wurden, und braucht ein Programm, das ihr beim Sortieren hilft.

Die meisten primitiven Werte sollten unkomplizierte Etiketten bekommen. Für Zahlen möchte sie Strings, die "This is the number 2.0" lauten (wenn die Zahl 2 war). Jen möchte dieselbe Ausgabe für Ganzzahlen und Gleitkommazahlen.

Es gibt ein paar Box-Schnittstellen, die entpackt werden müssen, um an ihren Inhalt zu kommen. Für eine NumberBox möchte sie Strings, die "This is a box containing the number 3.0" lauten (wenn die Methode Number() 3 zurückgibt). Für eine FancyNumberBox möchte sie Strings, die "This is a fancy box containing the number 4.0" lauten, aber nur, wenn der Typ ein FancyNumber ist.

Alles Unerwartete sollte "Return to sender" ausgeben, damit Jen es dorthin zurückschicken kann, wo es hergekommen ist.

1. Einfache Zahlen beschreiben

Jen möchte, dass Zahlen Strings wie "This is the number 2.0" zurückgeben (mit einer Nachkommastelle):

fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3

2. Eine Zahlenbox beschreiben

Jen möchte, dass Zahlenboxen Strings wie "This is a box containing the number 2.0" zurückgeben (wieder mit einer Nachkommastelle):

fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0

3. Eine Methode implementieren, die die Zahl aus einer Fancy-Number-Box extrahiert

Jen braucht eine Hilfsfunktion, um die Zahl aus einer FancyNumberBox zu extrahieren. Wenn die FancyNumberBox ein FancyNumber ist, extrahiere ihren Wert und wandle ihn von einem string in einen int um. Jeder andere Typ von FancyNumberBox sollte 0 zurückgeben.

fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0

4. Eine Fancy-Number-Box beschreiben

Wenn die FancyNumberBox ein FancyNumber ist, möchte Jen Strings, die "This is a fancy box containing the number 4.0" lauten. Jeder andere Typ von FancyNumberBox sollte "This is a fancy box containing the number 0.0" ausgeben.

fmt.Println(DescribeFancyNumberBox(FancyNumber{"10"}))
// Output: This is a fancy box containing the number 10.0
fmt.Println(DescribeFancyNumberBox(AnotherFancyNumber{"4"}))
// Output: This is a fancy box containing the number 0.0

HINWEIS: Wir sollten die Funktion ExtractFancyNumber verwenden!

5. DescribeAnything implementieren, das alle anderen nutzt

Das ist die Hauptfunktion, die Jen braucht und die jede beliebige Eingabe annimmt. DescribeAnything sollte anhand des Typs des übergebenen Werts an die anderen Funktionen delegieren. Genauer gesagt:

  • int und float64 sollten beide an DescribeNumber delegieren
  • NumberBox sollte an DescribeNumberBox delegieren
  • FancyNumberBox sollte an DescribeFancyNumberBox delegieren
  • alles andere sollte "Return to sender" ergeben
fmt.Println(DescribeAnything(numberBoxContaining{12.345}))
// Output: This is a box containing the number 12.3
fmt.Println(DescribeAnything("some string"))
// Output: Return to sender
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Go Exercism

Bereit, mit Sortierraum zu starten?

Melde dich bei Exercism an, um Go mit 34 Konzepte166 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.