Что нового

Что выбрать: Switch или Select ?

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
в теме о справке прочитал вот это
AZJIO [?]
Просто я около 2-3 лет использовал Select и даже находил в этом плюс. Потом все скрипты переписывал на Switch.
AZJIO [?]
Выбор между Switch и Select однозначно в сторону Switch, потому что в 99% проверяется событие, а не постороннее условие.
раньше как то не вникал, а когда самому понадобилось использовать, то использовал
Код:
Select

Но исходя из рассуждений AZJIO я теперь в некотором замешательстве.
перечитал справку. да, есть разница
Switch - сравнивает значения с исходным
Select - проверяет условие (надеюсь правильно понял)
в одном моем коде несколько раз используется Select. Заменил на Switch. Разницы не заметил.
Хотелось бы услышать объяснения по поводу этих ключевых слов. так когда же рациональнее использовать Select, а когда Switch ?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
При использовании switch сравнивается значение со значениями в ветвях - в коей ветке сравнение вернёт true тот код и выполнится.
Код:
$msg-GUIGetMsg()
Switch $msg
	Case -3
		Exit
	Case -2
		ContinueLoop
EndSwitch

В select проверяется истинность выражений.
Код:
Select
	Case $cmdline[0]<>0
		Select
			Case $cmdline[1]=1
				Send('`')
		EndSelect
EndSelect

Принципиальной разницы между ними нет, используешь то что удобно в данный момент.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
приведу свой пример. для пояснения вопроса. ситуация одна.
Код:
$string = FileOpenDialog('','','(*.*)')

If Not @error Then
	$flag = 0
ElseIf @error Then
	$flag = 1
EndIf
; Можно так.
Select
	Case $flag = 0
		MsgBox(0,'Select','Нет ошибки')
	Case $flag = 1
		MsgBox(0,'Select','Ошибка')
EndSelect
;А можно так. 
 Switch $flag
	Case 0
		MsgBox(0,'Switch','Нет ошибки')
	Case 1
		MsgBox(0,'Switch','Ошибка')
EndSwitch
;а как лучше?

Прошу извинить, если вопрос простой. Я любитель программирования. поэтому прилично мало знаю :smile:
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
$string = FileOpenDialog('','','(*.*)')
Select
	Case @error
		Exit
EndSelect

Здесь select предпочтительней, т к Case @error значит если @error<>0, то ... Можно не указывать код ошибки. А $flag не нужна совсем.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
пример общий..я лишь показал, что в некоем коде формируется переменная, значение которой будет использоваться далее. в данном примере это $flag
эта переменная может получать разные значения.
эта же переменная может приходить и из параметров функции
например
Код:
_FO_FileSearch ( $sPath [, $sMask = '*' [, $fInclude=True [, $iDepth=125 [, $iFull=1 [, $iArray=1 [, $iTypeMask=1 [, $sLocale=0[, $vExcludeFolders = ''[, $iExcludeDepth = -1]]]]]]]]] )

один параметр может иметь несколько значений.
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
В select ты можешь пихать любые условия, никак меж собой не связаные
Код:
Select
	Case Not @Compiled
		MsgBox(32,'','откомпилируй же меня')
		Exit
	Case Not $cmdline[0]
		Exit
EndSelect

Если сравниваешь одно значение (тот же @error), лучше switch, к тому же switch позволяет сравнивать с диапазоном значений.
Код:
$a='1'
Switch $a
	Case 0 to 9,15,17
		MsgBox(32,'',1)
EndSwitch
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
joiner
Попробуй представить что данный код интерпретируется и некоторая конструкция принимает значения конструкции скрипта. Например количество блоков Case неизвестно, значит внутренняя конструкция никак не может использовать нативный switch в C++. Я представляю так: интерпретатор либо встречает Switch, и записывает её подвыражение в переменную, далее читает Case, парсит его и сравнивает под-условие с ранее сохранённым элементом. При Select выполняется почти также, только проверяется самостоятельное под-условия в Case. Теоретически механизм практически одинаковый, только Switch первую переменную интерпретирует 1 раз, а потом использует внутренне, а Select первую переменную $msg интерпретирует на стороне скрипта в каждом Case.

Пример показывающий, что Select работает почти в 2 раза медленнее Switch
Код:
$z = 2
$s = 2
$timer1 = TimerInit()
For $i = 1 To 1000
	Switch 1
		Case 2
			$s = $z
		Case 3
			$s = $z
		Case 4
			$s = $z
		Case Else
			$s = $z
	EndSwitch
Next
$timer1 = Round(TimerDiff($timer1), 2) & ' мсек'

$timer2 = TimerInit()
For $i = 1 To 1000
	Select
		Case 1 = 2
			$s = $z
		Case 1 = 3
			$s = $z
		Case 1 = 4
			$s = $z
		Case Else
			$s = $z
	EndSelect
Next
$timer2 = Round(TimerDiff($timer2), 2) & ' мсек'
MsgBox(0, "Время выполнения", 'Switch : ' & $timer1 & ' мсек' & @LF & 'Select : ' & $timer2)


Ну и логически читать конструкцию удобнее если она сделана локанично, меньше слов при тех же возможностях. Понятно что при использовании Switch сверяется с одним значением, а при Select такого сказать нельзя, пока не проверишь все Case, что они содержит сравнение с $msg. А если поверишь на слово, то можно получить подставу.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
AZJIO [?]
только Switch первую переменную интерпретирует 1 раз, а потом использует внутренне, а Select первую переменную $msg интерпретирует на стороне скрипта в каждом Case.
то есть при множестве Case Switch их обрабатывает быстрее, повторно не обращается к переменной, Select при каждом Case опять читает(интерпретирует) переменную. это будет ощутимо именно при множественных Case
если я правильно понял


Добавлено:
Сообщение автоматически объединено:

в принципе через раз. то Switch быстрее, то Select.
все-таки, думаю, что проверять нужно на куче событий..в своем коде я проверяю значение флага, которое может быть одно из двух. разница не будет заметна. то есть проверить что флаг принес 1 или 0 не нужно затрачивать время и ресурс. возможно при сложных вычислениях или поиске разница будет заметна
 
Верх