Ответ 1
Как упоминалось в комментариях, Go не поддерживает трехмерные однострочные. Самая короткая форма, которую я могу придумать, такова:
var c int
if c = b; a > b {
c = a
}
Могу ли я написать простой оператор if-else с присвоением переменной в go (golang), как я бы сделал в php (например):
$var = ( $a > $b )? $a: $b;
В настоящее время я должен использовать следующее:
var c int
if a > b {
c = a
} else {
c = b
}
Извините, я не могу запомнить имя, если этот оператор управления, и я не смог найти информацию через поиск на сайте и в google.:/
Как упоминалось в комментариях, Go не поддерживает трехмерные однострочные. Самая короткая форма, которую я могу придумать, такова:
var c int
if c = b; a > b {
c = a
}
Я часто использую следующее:
c := b
if a > b {
c = a
}
в основном то же, что и @Not_a_Golfer, но используя тип вывода.
Как уже упоминалось, Go
не поддерживает троичных однострочников. Тем не менее, я написал вспомогательную функцию, которая может помочь вам достичь того, что вы хотите.
// IfThenElse evaluates a condition, if true returns the first parameter otherwise the second
func IfThenElse(condition bool, a interface{}, b interface{}) interface{} {
if condition {
return a
}
return b
}
Вот несколько тестовых случаев, чтобы показать, как вы можете использовать его
func TestIfThenElse(t *testing.T) {
assert.Equal(t, IfThenElse(1 == 1, "Yes", false), "Yes")
assert.Equal(t, IfThenElse(1 != 1, nil, 1), 1)
assert.Equal(t, IfThenElse(1 < 2, nil, "No"), nil)
}
Для забавы я написал более полезные служебные функции, такие как:
IfThen(1 == 1, "Yes") // "Yes"
IfThen(1 != 1, "Woo") // nil
IfThen(1 < 2, "Less") // "Less"
IfThenElse(1 == 1, "Yes", false) // "Yes"
IfThenElse(1 != 1, nil, 1) // 1
IfThenElse(1 < 2, nil, "No") // nil
DefaultIfNil(nil, nil) // nil
DefaultIfNil(nil, "") // ""
DefaultIfNil("A", "B") // "A"
DefaultIfNil(true, "B") // true
DefaultIfNil(1, false) // 1
FirstNonNil(nil, nil) // nil
FirstNonNil(nil, "") // ""
FirstNonNil("A", "B") // "A"
FirstNonNil(true, "B") // true
FirstNonNil(1, false) // 1
FirstNonNil(nil, nil, nil, 10) // 10
FirstNonNil(nil, nil, nil, nil, nil) // nil
FirstNonNil() // nil
Если вы хотите использовать любой из них, вы можете найти их здесь https://github.com/shomali11/util
Спасибо за указание на правильный ответ.
Я только что проверил часто задаваемые вопросы по Голангу (да), и в нем четко сказано, что это не доступно на языке:
Go имеет оператор?:?
В Go нет троичной формы. Вы можете использовать следующее для достижения того же результата:
if expr { n = trueVal } else { n = falseVal }
найдена дополнительная информация, которая может представлять интерес для данной темы:
Один из возможных способов сделать это только в одной строке, используя карту, просто я проверяю ли a > b
, если это true
, я назначаю c
к иначе a
b
c := map[bool]int{true: a, false: b}[a > b]
Тем не менее, это выглядит потрясающе, но в некоторых случаях это может быть НЕ идеальным решением из-за порядка оценки. Например, если я проверяю, является ли объект не nil
получим из него какое-либо свойство, посмотрите на следующий фрагмент кода, который будет myObj equals nil
panic
в случае, если myObj equals nil
type MyStruct struct {
field1 string
field2 string
}
var myObj *MyStruct
myObj = nil
myField := map[bool]string{true: myObj.field1, false: "empty!"}[myObj != nil}
Поскольку карта будет создана и построена в первую очередь, прежде чем оценивать условие, поэтому в случае myObj = nil
это просто вызовет панику.
Не забудьте упомянуть, что вы все еще можете выполнить условия в одной простой строке, проверьте следующее:
var c int
...
if a > b { c = a } else { c = b}
Иногда я пытаюсь использовать анонимную функцию для достижения определения и назначения в одной строке. как ниже:
a, b = 4, 8
c := func() int {
if a >b {
return a
}
return b
} ()
Очень похожая конструкция доступна на языке
**if <statement>; <evaluation> {
[statements ...]
} else {
[statements ...]
}*
*
то есть.
if path,err := os.Executable(); err != nil {
log.Println(err)
} else {
log.Println(path)
}
Вы можете использовать замыкание для этого:
func doif(b bool, f1, f2 func()) {
switch{
case b:
f1()
case !b:
f2()
}
}
func dothis() { fmt.Println("Condition is true") }
func dothat() { fmt.Println("Condition is false") }
func main () {
condition := true
doif(condition, func() { dothis() }, func() { dothat() })
}
Единственный недостаток синтаксиса замыкания в Go - отсутствие псевдонима для функции возврата по умолчанию с нулевым параметром по умолчанию, тогда было бы намного лучше (подумайте, например, как вы объявляете литералы map, array и slice только с именем типа).
Или даже более короткая версия, как только что предложил комментатор:
func doif(b bool, f1, f2 func()) {
switch{
case b:
f1()
case !b:
f2()
}
}
func dothis() { fmt.Println("Condition is true") }
func dothat() { fmt.Println("Condition is false") }
func main () {
condition := true
doif(condition, dothis, dothat)
}
Вам все равно нужно будет использовать замыкание, если вам нужно задать параметры для функций. Это можно избежать в случае передачи методов, а не только функций, я думаю, где параметры - это структура, связанная с методами.
Используйте лямбда-функцию вместо тернарного оператора
Пример 1
дать максимум int
package main
func main() {
println( func(a,b int) int {if a>b {return a} else {return b} }(1,2) )
}
Пример 2
Предположим, у вас есть эта функция must(err error)
для обработки ошибок, и вы хотите использовать ее, когда условие не выполняется.
(наслаждайтесь на https://play.golang.com/p/COXyo0qIslP)
package main
import (
"errors"
"log"
"os"
)
// must is a little helper to handle errors. If passed error != nil, it simply panics.
func must(err error) {
if err != nil {
log.Println(err)
panic(err)
}
}
func main() {
tmpDir := os.TempDir()
// Make sure os.TempDir didn't return empty string
// reusing my favourite 'must' helper
// Isn't that kinda creepy now though?
must(func() error {
var err error
if len(tmpDir) > 0 {
err = nil
} else {
err = errors.New("os.TempDir is empty")
}
return err
}()) // Don't forget that empty parentheses to invoke the lambda.
println("We happy with", tmpDir)
}