if statement - then - ¿Cómo hacer una sola línea si otra declaración?
if then else visual basic (9)
A menudo uso lo siguiente:
c := b
if a > b {
c = a
}
básicamente lo mismo que @ Not_a_Golfer''s pero usando inferencia de tipos .
¿Puedo escribir una simple instrucción if-else con asignación variable en go (golang) como lo haría en php (por ejemplo):
$var = ( $a > $b )? $a: $b;
Actualmente tengo que usar lo siguiente:
var c int
if a > b {
c = a
} else {
c = b
}
Lo siento, no puedo recordar el nombre de esta declaración de control y no pude encontrar la información a través del sitio y la búsqueda de Google. : /
A veces, trato de usar la función anónima para lograr que la definición y la asignación sucedan en la misma línea. como abajo:
a, b = 4, 8
c := func() int {
if a >b {
return a
}
return b
} ()
Como los otros mencionaron,
Go
no es compatible con frases ingeniosas ternarias.
Sin embargo, escribí una función de utilidad que podría ayudarlo a lograr lo que desea.
// 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
}
Aquí hay algunos casos de prueba para mostrar cómo puede usarlo
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)
}
Por diversión, escribí funciones de utilidad más útiles como:
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
Si desea utilizar alguno de estos, puede encontrarlos aquí https://github.com/shomali11/util
Como se mencionó en los comentarios, Go no admite revestimientos ternarios. La forma más corta que se me ocurre es esta:
var c int
if c = b; a > b {
c = a
}
Gracias por señalar hacia la respuesta correcta.
Acabo de consultar las Preguntas frecuentes de Golang (duh) y dice claramente que esto no está disponible en el idioma:
¿Go tiene el operador?
No hay forma ternaria en Go. Puede usar lo siguiente para lograr el mismo resultado:
if expr { n = trueVal } else { n = falseVal }
información adicional encontrada que podría ser de interés sobre el tema:
Puede usar un cierre para esto:
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() })
}
La única queja que tengo con la sintaxis de cierre en Go es que no hay un alias para la función predeterminada de retorno cero del parámetro cero, entonces sería mucho mejor (piense cómo declara literales map, array y slice con solo un nombre de tipo).
O incluso la versión más corta, como acaba de sugerir un comentarista:
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)
}
Aún necesitaría usar un cierre si necesitara dar parámetros a las funciones. Esto podría obviarse en el caso de pasar métodos en lugar de solo funciones, creo, donde los parámetros son la estructura asociada con los métodos.
Una construcción muy similar está disponible en el idioma.
**if <statement>; <evaluation> {
[statements ...]
} else {
[statements ...]
}*
* *
es decir
if path,err := os.Executable(); err != nil {
log.Println(err)
} else {
log.Println(path)
}
Una forma posible de hacer esto en una sola línea mediante el uso de un mapa, simple, estoy verificando si
a > b
si es
true
, estoy asignando
c
a
a
contrario
b
c := map[bool]int{true: a, false: b}[a > b]
Sin embargo, esto se ve increíble, pero en algunos casos puede que NO sea la solución perfecta debido al orden de evaluación.
Por ejemplo, si estoy verificando si un objeto no es
nil
obtengo alguna propiedad de él, mire el siguiente fragmento de código que entrará en
panic
en caso de que
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}
Debido a que el mapa se creará y construirá primero antes de evaluar la condición, en caso de
myObj = nil
esto simplemente entrará en pánico.
Sin olvidar mencionar que aún puede hacer las condiciones en una sola línea simple, verifique lo siguiente:
var c int
...
if a > b { c = a } else { c = b}
Utilice la función lambda en lugar del operador ternario
Ejemplo 1
para dar el máximo int
package main
func main() {
println( func(a,b int) int {if a>b {return a} else {return b} }(1,2) )
}
Ejemplo 2
Suponga que tiene esta función
must(err error)
para manejar errores y desea usarla cuando no se cumple una condición.
(disfruta en
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)
}