golang switch

Пользователь

от newell , в категории: Общие вопросы , 4 года назад

Расскажите, пожалуйста, на примерах, как в Golang’е использовать конструкцию switch case? Знаю как в C++ это делается, а вот в Golang’е не могу понять.


Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp Pocket

7 ответов

Пользователь

от bradly.ledner , 4 года назад

Зайди на русскоязычный сайт golangs.org. В серии уроков по Golang ты найдёшь урок, который называется - Цикл for, if-else-switch, True-False и операторы сравнения в Golang. В нём помимо свич есть также все основные знания логики.


Пользователь

от anastacio.hane , 4 года назад

switch в Go более общий, чем в C. Выражения не должны быть константами или даже целыми числами, cases оцениваются сверху вниз, пока не будет найдено совпадение, и если switch не имеет выражения, он включается на true (то есть как будто бы было указано switch(true){}). Поэтому возможно - и идиоматично - писать if-else-if-else цепочку как switch.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func unhex(c byte) byte {
   switch {
   case '0' <= c && c <= '9':
       return c - '0'
   case 'a' <= c && c <= 'f':
       return c - 'a' + 10
   case 'A' <= c && c <= 'F':
       return c - 'A' + 10
   }
   return 0
}


Пользователь

от anastacio.hane , 4 года назад

Нет автоматического провала (то есть случая использования нескольких case одновременно для объединения их в один результат), но случаи (cases) могут быть представлены в разделенных запятыми списках.


Пользователь

от anastacio.hane , 4 года назад
1
2
3
4
5
6
7
func shouldEscape(c byte) bool {
   switch c {
   case ' ', '?', '&', '=', '#', '+', '%':
       return true
   }	
   return false
}

 

Хотя они не так распространены в Go, как в других C-подобных языках, операторы break могут использоваться для раннего завершения switch. Иногда, однако, необходимо выйти из окружающего цикла (не switch цикла), и в Go это можно сделать, поставив метку в цикле и выходя (breaking) к этой метке. Следующий пример показывает оба варианта использования.

Пользователь

от anastacio.hane , 4 года назад

Loop:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  for n := 0; n < len(src); n += size {
       switch {
       case src[n] < sizeOne:
           if validateOnly {
               break
           }
           size = 1
           update(src[n])
 
       case src[n] < sizeTwo:
           if n+1 >= len(src) {
               err = errShortInput
               break Loop
           }
           if validateOnly {
               break
           }
           size = 2
           update(src[n] + src[n+1]<<shift)
       }
   }

Конечно, оператор continue также принимает необязательную метку, но это относится только к циклам.

 

Вот процедура сравнения для байтовых срезов, которая использует два оператора switch:

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Compare возвращает число сравнивая два байтовых среза,
// лексикографически.
// Результат будет 0 если a == b, -1 если a < b, 
// и +1 если a > b
func Compare(a, b []byte) int {
   for i := 0; i < len(a) && i < len(b); i++ {
       switch {
       case a[i] > b[i]:
           return 1
       case a[i] < b[i]:
           return -1
       }
   }
   switch {
   case len(a) > len(b):
       return 1
   case len(a) < len(b):
       return -1
   }
   return 0
}


Пользователь

от anastacio.hane , 4 года назад

Переключатель типов (Type switch)

switch также может быть использован для обнаружения динамического типа переменной интерфейса. Такой type switch использует синтаксис утверждения типа (type assertion) с ключевым словом type в круглых скобках. Если switch объявляет переменную в выражении, переменная будет иметь соответствующий тип в каждом условии. Также идиоматично повторно использовать имя в таких случаях, фактически объявляя новую переменную с тем же именем, но с разным типом в каждом случае.

 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
   // %T печатает type, который t имеет
   fmt.Printf("неожидаемый тип %T\n", t)
case bool:
   // t имеет type bool
   fmt.Printf("boolean %t\n", t)
case int:
   // t имеет type int
   fmt.Printf("integer %d\n", t)
case *bool:
   // t имеет type *bool
   fmt.Printf("pointer к boolean %t\n", *t) 
case *int:
   // t имеет type *int
   fmt.Printf("pointer к integer %d\n", *t) 
}


Пользователь

от newell , 4 года назад

Спасибо большое, ребят, за то, что смогли мне наконец-таки объяснить это. Теперь всё стало намного понятнее. Буду теперь нарешивать задачки с использованием свичей.