当前位置: 首页 > news >正文

go 流程控制之switch 语句介绍

go 流程控制之switch 语句介绍

文章目录

  • go 流程控制之switch 语句介绍
    • 一、switch语句介绍
      • 1.1 认识 switch 语句
      • 1.2 基本语法
    • 二、Go语言switch语句中case表达式求值顺序
      • 2.1 switch语句中case表达式求值次序介绍
      • 2.2 switch语句中case表达式的求值次序特点
    • 三、switch 语句的灵活性
      • 3.1 switch 语句各表达式的求值结果支持各种类型值
      • 3.2 switch 语句支持声明临时变量
      • 3.3 case 语句支持表达式列表
      • 3.4 取消了默认执行下一个 case 代码逻辑的语义
    • 四、type switch
    • 五、跳不出循环的 break
    • 六、switch与if 比较
      • 相似之处:
      • 不同之处:

一、switch语句介绍

1.1 认识 switch 语句

我们先通过一个例子来直观地感受一下 switch 语句的优点。在一些执行分支较多的场景下,使用 switch 分支控制语句可以让代码更简洁,可读性更好。

比如下面例子中的 readByExt 函数会根据传入的文件扩展名输出不同的日志,使用 if 语句进行分支控制:

func readByExt(ext string) {if ext == "json" {println("read json file")} else if ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "gif" {println("read image file")} else if ext == "txt" || ext == "md" {println("read text file")} else if ext == "yml" || ext == "yaml" {println("read yaml file")} else if ext == "ini" {println("read ini file")} else {println("unsupported file extension:", ext)}
}

如果用 switch 改写上述例子代码,我们可以这样来写:

func readByExtBySwitch(ext string) {switch ext {case "json":println("read json file")case "jpg", "jpeg", "png", "gif":println("read image file")case "txt", "md":println("read text file")case "yml", "yaml":println("read yaml file")case "ini":println("read ini file")default:println("unsupported file extension:", ext)}
}

从代码呈现的角度来看,针对这个例子,使用 switch 语句的实现要比 if 语句的实现更加简洁紧凑。

简单来说,readByExtBySwitch 函数就是将输入参数 ext 与每个 case 语句后面的表达式做比较,如果相等,就执行这个 case 语句后面的分支,然后函数返回。

1.2 基本语法

在Go编程语言中,switch语句的基本语法如下:

switch initStmt; expr {case expr1:// 执行分支1case expr2:// 执行分支2case expr3_1, expr3_2, expr3_3:// 执行分支3case expr4:// 执行分支4... ...case exprN:// 执行分支Ndefault: // 执行默认分支
}

我们按语句顺序来分析一下:

  • 首先 switch 语句第一行由 switch 关键字开始,它的后面通常接着一个表达式(expr),这句中的 initStmt 是一个可选的组成部分。和 iffor 语句一样,我们可以在 initStmt 中通过短变量声明定义一些在 switch 语句中使用的临时变量。
  • 接下来,switch 后面的大括号内是一个个代码执行分支,每个分支以 case 关键字开始,每个 case 后面是一个表达式或是一个逗号分隔的表达式列表。
  • 最后,还有一个以 default 关键字开始的特殊分支,被称为默认分支default 子句是可选的,如果没有一个case子句匹配expression的值,将执行default子句中的代码块。

最后,我们再来看 switch 语句的执行流程:

  • 首先,switch 语句会用 expr 的求值结果与各个 case 中的表达式结果进行比较,如果发现匹配的 case,也就是 case 后面的表达式,或者表达式列表中任意一个表达式的求值结果与 expr 的求值结果相同,那么就会执行该 case 对应的代码分支,分支执行后,switch 语句也就结束了。
  • 如果所有 case 表达式都无法与 expr 匹配,那么程序就会执行 default 默认分支,并且结束 switch 语句。

二、Go语言switch语句中case表达式求值顺序

2.1 switch语句中case表达式求值次序介绍

接下来,我们再来看看,在有多个 case 执行分支的 switch 语句中,Go 是按什么次序对各个 case 表达式进行求值,并且与 switch 表达式(expr)进行比较的?

我们先来看一段示例代码,这是一个一般形式的 switch 语句,为了能呈现 switch 语句的执行次序,以多个输出特定日志的函数作为 switch 表达式以及各个 case 表达式:

func case1() int {println("eval case1 expr")return 1
}func case2_1() int {println("eval case2_1 expr")return 0 
}
func case2_2() int {println("eval case2_2 expr")return 2 
}func case3() int {println("eval case3 expr")return 3
}func switchexpr() int {println("eval switch expr")return 2
}func main() {switch switchexpr() {case case1():println("exec case1")case case2_1(), case2_2():println("exec case2")case case3():println("exec case3")default:println("exec default")}
}

执行一下这个示例程序,我们得到如下结果:

eval switch expr
eval case1 expr
eval case2_1 expr
eval case2_2 expr
exec case2

从输出结果中我们看到,Go 先对 switch expr 表达式进行求值,然后再按 case 语句的出现顺序,从上到下进行逐一求值。在带有表达式列表的 case 语句中,Go 会从左到右,对列表中的表达式进行求值,比如示例中的 case2_1 函数就执行于 case2_2 函数之前。

如果 switch 表达式匹配到了某个 case 表达式,那么程序就会执行这个 case 对应的代码分支,比如示例中的“exec case2”。这个分支后面的 case 表达式将不会再得到求值机会,比如示例不会执行 case3 函数。这里要注意一点,即便后面的 case 表达式求值后也能与 switch 表达式匹配上,Go 也不会继续去对这些表达式进行求值了,这是switch语句的工作原理。

除了这一点外,你还要注意 default 分支。无论 default 分支出现在什么位置,它都只会在所有 case 都没有匹配上的情况下才会被执行的

不知道你有没有发现,这里其实有一个优化小技巧,考虑到 switch 语句是按照 case 出现的先后顺序对 case 表达式进行求值的,那么如果我们将匹配成功概率高的 case 表达式排在前面,就会有助于提升 switch 语句执行效率。这点对于 case 后面是表达式列表的语句同样有效,我们可以将匹配概率最高的表达式放在表达式列表的最左侧。

2.2 switch语句中case表达式的求值次序特点

Go语言switch语句中case表达式的求值次序特点:

  1. switch语句首先求值switch表达式,然后按case出现顺序逐一求值case表达式。
  2. 一旦某个case表达式匹配成功后,就执行对应的代码块,之后case不再求值。
  3. 即使后续的case表达式匹配成功,也不会再求值。
  4. 所有case都不匹配的情况下,会执行默认的default案例。
  5. default位置灵活,可以放在开头或结尾。
  6. case后带表达式列表时,会从左到右求值列表中的表达式。
  7. 将匹配概率高的case排在前面,可以优化执行效率。

三、switch 语句的灵活性

3.1 switch 语句各表达式的求值结果支持各种类型值

首先,switch 语句各表达式的求值结果可以为各种类型值,只要它的类型支持比较操作就可以了。

Go 语言只要类型支持比较操作,都可以作为 switch 语句中的表达式类型。比如整型、布尔类型、字符串类型、复数类型、元素类型都是可比较类型的数组类型,甚至字段类型都是可比较类型的结构体类型也可以。下面就是一个使用自定义结构体类型作为switch表达式类型的例子:

type person struct {name stringage  int
}func main() {p := person{"tom", 13}switch p {case person{"tony", 33}:println("match tony")case person{"tom", 13}:println("match tom")case person{"lucy", 23}:println("match lucy")default:println("no match")}
}

实际开发过程中,以结构体类型为 switch表达式类型的情况并不常见,这里举这个例子仅是为了说明 Go switch 语句对各种类型支持的广泛性。

而且,当 switch 表达式的类型为布尔类型时,如果求值结果始终为 true,那么我们甚至可以省略 switch 后面的表达式,比如下面例子:

// 带有initStmt语句的switch语句
switch initStmt; {case bool_expr1:case bool_expr2:... ...
}// 没有initStmt语句的switch语句
switch {case bool_expr1:case bool_expr2:... ...
}

注意:在带有 initStmt 的情况下,如果我们省略 switch 表达式,那么 initStmt 后面的分号不能省略,因为 initStmt 是一个语句。

3.2 switch 语句支持声明临时变量

在前面介绍 switch 语句的一般形式中,我们看到,和 if、for 等控制结构语句一样,switch 语句的 initStmt 可用来声明只在这个 switch 隐式代码块中使用的变量,这种就近声明的变量最大程度地缩小了变量的作用域。

示例:

switch x := someFunction(); x {
case 1:fmt.Println("x is 1")
case 2:fmt.Println("x is 2")
default:fmt.Println("x is something else")
}// 这里无法访问 x,因为它的作用域仅限于 switch 语句

在上面的示例中,x是一个局部变量,只在switch语句内部可见。这可以有效地限制变量的生存期和可见性,从而提高代码的清晰度和健壮性。这是Go语言在控制结构中的一种好实践。

3.3 case 语句支持表达式列表

在Go的switch语句中,case语句支持表达式列表,一个分支可以有多个值,多个case值中间使用英文逗号分隔。这意味着你可以在一个case子句中列出多个表达式,以匹配其中任何一个表达式。如果switch表达式的值与列表中的任何一个表达式匹配,相应的case分支将被执行。

func checkWorkday(a int) {switch a {case 1, 2, 3, 4, 5:println("it is a work day")case 6, 7:println("it is a weekend day")default:println("are you live on earth")}
}

3.4 取消了默认执行下一个 case 代码逻辑的语义

在 C 语言中,如果匹配到的 case 对应的代码分支中没有显式调用 break 语句,那么代码将继续执行下一个 case 的代码分支,这种“隐式语义”并不符合日常算法的常规逻辑,这也经常被诟病为 C 语言的一个缺陷。要修复这个缺陷,我们只能在每个 case 执行语句中都显式调用 break。

Go 语言中的 Swith 语句就修复了 C 语言的这个缺陷,取消了默认执行下一个 case 代码逻辑的“非常规”语义,每个 case 对应的分支代码执行完后就结束 switch 语句。

如果在少数场景下,你需要执行下一个 case 的代码逻辑,你可以显式使用 Go 提供的关键字 fallthrough 来实现,fallthrough语法可以执行满足条件的case的下一个case,是为了兼容C语言中的case设计的。下面就是一个使用 fallthrough 的 switch 语句的例子,我们简单来看一下:

func case1() int {println("eval case1 expr")return 1
}func case2() int {println("eval case2 expr")return 2
}func switchexpr() int {println("eval switch expr")return 1
}func main() {switch switchexpr() {case case1():println("exec case1")fallthroughcase case2():println("exec case2")fallthroughdefault:println("exec default")}
}

执行一下这个示例程序,我们得到这样的结果:

eval switch expr
eval case1 expr
exec case1
exec case2
exec default

我们看到,switch expr 的求值结果与 case1 匹配成功,Go 执行了 case1 对应的代码分支。而且,由于 case1 代码分支中显式使用了 fallthrough,执行完 case1 后,代码执行流并没有离开 switch 语句,而是继续执行下一个 case,也就是 case2 的代码分支。

这里有一个注意点,由于 fallthrough 的存在,Go 不会对 case2 的表达式做求值操作,而会直接执行 case2 对应的代码分支。而且,在这里 case2 中的代码分支也显式使用了 fallthrough,于是最后一个代码分支,也就是 default 分支对应的代码也被执行了。

另外,还有一点要注意的是,如果某个 case 语句已经是 switch 语句中的最后一个 case 了,并且它的后面也没有 default 分支了,那么这个 case 中就不能再使用 fallthrough,否则编译器就会报错。

到这里,我们看到 Go 的 switch 语句不仅修复了 C 语言 switch 的缺陷,还为 Go 开发人员提供了更大的灵活性,我们可以使用更多类型表达式作为 switch 表达式类型,也可以使用 case 表达式列表简化实现逻辑,还可以自行根据需要,确定是否使用 fallthrough 关键字继续向下执行下一个 case 的代码分支。

四、type switch

“type switch”这是一种特殊的 switch 语句用法,我们通过一个例子来看一下它具体的使用形式:

func main() {var x interface{} = 13switch x.(type) {case nil:println("x is nil")case int:println("the type of x is int")case string:println("the type of x is string")case bool:println("the type of x is string")default:println("don't support the type")}
}

我们看到,这个例子中 switch 语句的形式与前面是一致的,不同的是 switch 与 case 两个关键字后面跟着的表达式。

switch 关键字后面跟着的表达式为x.(type),这种表达式形式是 switch 语句专有的,而且也只能在 switch 语句中使用。这个表达式中的 x 必须是一个接口类型变量,表达式的求值结果是这个接口类型变量对应的动态类型。

什么是一个接口类型的动态类型呢?我们简单解释一下。以上面的代码 var x interface{} = 13 为例,x 是一个接口类型变量,它的静态类型为interface{},如果我们将整型值 13 赋值给 x,x 这个接口变量的动态类型就为 int。关于接口类型变量的动态类型,我们后面还会详细讲,这里先简单了解一下就可以了。

接着,case 关键字后面接的就不是普通意义上的表达式了,而是一个个具体的类型。这样,Go 就能使用变量 x 的动态类型与各个 case 中的类型进行匹配,之后的逻辑就都是一样的了。

现在我们运行上面示例程序,输出了 x 的动态变量类型:

the type of x is int

不过,通过 x.(type) ,我们除了可以获得变量 x 的动态类型信息之外,也能获得其动态类型对应的值信息,现在我们把上面的例子改造一下:

func main() {var x interface{} = 13switch v := x.(type) {case nil:println("v is nil")case int:println("the type of v is int, v =", v)case string:println("the type of v is string, v =", v)case bool:println("the type of v is bool, v =", v)default:println("don't support the type")}
}

这里我们将 switch 后面的表达式由 x.(type) 换成了 v := x.(type) 。对于后者,你千万不要认为变量 v 存储的是类型信息,其实 v 存储的是变量 x 的动态类型对应的值信息,这样我们在接下来的 case 执行路径中就可以使用变量 v 中的值信息了。

然后,我们运行上面示例,可以得到 v 的动态类型和值:

the type of v is int, v = 13

另外,你可以发现,在前面的 type switch 演示示例中,我们一直使用 interface{}这种接口类型的变量,Go 中所有类型都实现了 interface{}类型,所以 case 后面可以是任意类型信息。

但如果在 switch 后面使用了某个特定的接口类型 I,那么 case 后面就只能使用实现了接口类型 I 的类型了,否则 Go 编译器会报错。你可以看看这个例子:

  type I interface {M()}type T struct {}func (T) M() {}func main() {var t Tvar i I = tswitch i.(type) {case T:println("it is type T")case int:println("it is type int")case string:println("it is type string")}}

在这个例子中,我们在 type switch 中使用了自定义的接口类型 I。那么,理论上所有 case 后面的类型都只能是实现了接口 I 的类型。但在这段代码中,只有类型 T 实现了接口类型 I,Go 原生类型 int 与 string 都没有实现接口 I,于是在编译上述代码时,编译器会报出如下错误信息:

19:2: impossible type switch case: i (type I) cannot have dynamic type int (missing M method)
21:2: impossible type switch case: i (type I) cannot have dynamic type string (missing M method)

五、跳不出循环的 break

这里,我们来看一个找出整型切片中第一个偶数的例子,使用 switch 分支结构:

func main() {var sl = []int{5, 19, 6, 3, 8, 12}var firstEven int = -1// find first even number of the interger slicefor i := 0; i < len(sl); i++ {switch sl[i] % 2 {case 0:firstEven = sl[i]breakcase 1:// do nothing}        }         println(firstEven) 
}

我们运行一下这个修改后的程序,得到结果为 12。

奇怪,这个输出的值与我们的预期的好像不太一样。这段代码中,切片中的第一个偶数是 6,而输出的结果却成了切片的最后一个偶数 12。为什么会出现这种结果呢?

这就是 Go 中 break 语句与 switch 分支结合使用会出现一个“小坑”。和我们习惯的 C 家族语言中的 break 不同,Go 语言规范中明确规定,不带 label 的 break 语句中断执行并跳出的,是同一函数内 break 语句所在的最内层的 for、switch 或 select。所以,上面这个例子的 break 语句实际上只跳出了 switch 语句,并没有跳出外层的 for 循环,这也就是程序未按我们预期执行的原因。

要修正这一问题,我们可以利用 labelbreak 语句试试。这里我们也直接看看改进后的代码:

func main() {var sl = []int{5, 19, 6, 3, 8, 12}var firstEven int = -1// find first even number of the interger slice
loop:for i := 0; i < len(sl); i++ {switch sl[i] % 2 {case 0:firstEven = sl[i]break loopcase 1:// do nothing}}println(firstEven) // 6
}

在改进后的例子中,我们定义了一个 label:loop,这个 label 附在 for 循环的外面,指代 for 循环的执行。当代码执行到“break loop”时,程序将停止 label loop 所指代的 for 循环的执行。

六、switch与if 比较

Go编程语言中的switch语句和if语句是用于控制程序流程的两个不同工具,它们可以用来执行条件性代码块,但它们在使用方式和适用场景上有所不同。

相似之处:

  • if语句和switch语句都用于根据某个条件执行不同的代码块。
  • 两者都可以用于处理多个条件或值的情况。

不同之处:

  • if语句通常用于处理更复杂的条件逻辑,可以检查任何布尔表达式。它是通用的条件控制工具。
  • switch语句专门用于根据一个表达式的值选择执行不同的代码块。它通常用于在多个值之间进行精确的比较。

if语句中,你可以编写任意复杂的条件,例如:

if condition1 {// 当condition1为真时执行这里的代码
} else if condition2 {// 当condition2为真时执行这里的代码
} else {// 如果以上条件都不为真,执行这里的代码
}

而在switch语句中,你主要是根据某个表达式的值进行选择,比较简洁:

switch expression {
case value1:// 当expression等于value1时执行这里的代码
case value2:// 当expression等于value2时执行这里的代码
default:// 如果expression不等于任何一个value,执行这里的代码
}

使用if语句更适合处理复杂的条件逻辑,而switch语句更适合在多个值之间进行简单的比较。

相关文章:

go 流程控制之switch 语句介绍

go 流程控制之switch 语句介绍 文章目录 go 流程控制之switch 语句介绍一、switch语句介绍1.1 认识 switch 语句1.2 基本语法 二、Go语言switch语句中case表达式求值顺序2.1 switch语句中case表达式求值次序介绍2.2 switch语句中case表达式的求值次序特点 三、switch 语句的灵活…...

sql 时间有偏差的解决方法

测试功能的时候发现记录的创建时间不对&#xff0c;死活对不上&#xff0c;下意识的以为是服务器时间有偏差&#xff0c;后来排查发现存入表中的时间是正常的&#xff0c;但是查询展示出来的时间是不对的&#xff0c;就去排查可能是查询sql格式化时间有问题&#xff0c;果不其然…...

Apache Lucene 7.0 - 索引文件格式

Apache Lucene 7.0 - 索引文件格式 文章目录 Apache Lucene 7.0 - 索引文件格式介绍定义反向索引字段类型段文档数量索引结构概述文件命名文件扩展名摘要锁文件 原文地址 介绍 这个文档定义了在这个版本的Lucene中使用的索引文件格式。如果您使用的是不同版本的Lucene&#xf…...

GEE:使用中文做变量和函数名写GEE代码

作者&#xff1a;CSDN _养乐多_ 啊&#xff1f;最近在编写GEE代码的时候&#xff0c;无意中发现 JavaScript 已经能够支持中文字符作为变量名和函数名&#xff0c;这个发现让我感到非常兴奋。这意味着以后在编程过程中&#xff0c;我可以更自由地融入中文元素&#xff0c;不再…...

针对量化交易SDK的XTP的初步摸索

这东西只要是调用API实现自动交易股票的&#xff0c;就不可能免费的接口。 并且用这些接口实现自动交易还得 归证券公司监管。比如 xtp出自 中泰证券&#xff0c;那么如果用xtp实现自动交易股票的软件&#xff0c;具体操作实盘的时候 不能跑再自己的电脑上&#xff0c;必须跑在…...

Unity编辑器从PC平台切换到Android平台下 Addressable 加载模型出现粉红色,类似于材质丢失的问题

Unity编辑器在PC平台下使用Addressable加载打包好的Cube&#xff0c;运行发现能正常显示。 而在切换到Android平台下&#xff0c;使用Addressable时加载AB包&#xff0c;生成Cube对象时&#xff0c;Cube模型呈现粉红色&#xff0c;出现类似材质丢失的问题。如下图所示。 这是…...

CSS 边框

CSS 边框属性 CSS边框属性允许你指定一个元素边框的样式和颜色。 在四边都有边框 红色底部边框 圆角边框 左侧边框带宽度&#xff0c;颜色为蓝色 边框样式 边框样式属性指定要显示什么样的边界。 border-style属性用来定义边框的样式 border-style 值: none: 默认无边框…...

Docker逃逸---CVE-2020-15257浅析

一、产生原因 在版本1.3.9之前和1.4.0~1.4.2的Containerd中&#xff0c;由于在网络模式为host的情况下&#xff0c;容器与宿主机共享一套Network namespace &#xff0c;此时containerd-shim API暴露给了用户&#xff0c;而且访问控制仅仅验证了连接进程的有效UID为0&#xff…...

Python学习 day03(注意事项)

数据容器 列表...

vue中的生命周期有什么,怎么用

Vue.js 的生命周期&#xff08;lifecycle&#xff09;是指 Vue 实例从创建到销毁的整个过程。Vue.js 常用的生命周期包括&#xff1a; beforeCreate&#xff1a;在实例被创建之前调用&#xff0c;此时组件的数据观测和事件机制都未被初始化。created&#xff1a;在实例创建完成…...

论文阅读:ECAPA-TDNN

1. 提出ECAPA-TDNN架构 TDNN本质上是1维卷积&#xff0c;而且常常是1维膨胀卷积&#xff0c;这样的一种结构非常注重context&#xff0c;也就是上下文信息&#xff0c;具体而言&#xff0c;是在frame-level的变换中&#xff0c;更多地利用相邻frame的信息&#xff0c;甚至跳过…...

【Unity】【VR】详解Oculus Integration输入

【背景】 以下内容适用于Oculus Integration开发VR场景,也就是OVR打头的Scripts,不适用于OpenXR开发场景,也就是XR打头Scripts。 【详解】 OVR的Input相对比较容易获取。重点在于区分不同动作机制的细节效果。 OVR Input的按键存在Button和RawButton两个系列 RawButton…...

vue axios封装

Vue.js 是一款前端框架&#xff0c;而 Axios 是一个基于 Promise 的 HTTP 请求客户端&#xff0c;通常用于发送 Ajax 请求。在Vue.js开发中&#xff0c;经常需要使用 Axios 来进行 HTTP 数据请求&#xff0c;为了更好的维护和使用 Axios&#xff0c;我们可以对其进行封装。下面…...

oracle、mysql、postgresql数据库的几种表关联方法

简介 在数据开发过程中&#xff0c;常常需要判断几个表直接的数据包含关系&#xff0c;便需要使用到一些特定的关键词进行处理。在数据库中常见的几种关联关系&#xff0c;本文以oracle、mysql、postgresql三种做演示 创建测试数据 oracle -- 创建表 p1 CREATE TABLE p1 (tx…...

什么是UML UML入门到放弃系列

1.定义 UML-Unified Modeling Language 统一建模语言&#xff0c;又称标准建模语言。是用来对软件密集系统进行可视化建模的一种语言。 2.UML的三个级别 《UML精粹》一书中把这三个级别称为概念级、规格说明级和实现级。 2.1 概念级 概念级的图示和源代码之间没有很强的关联。…...

vue3 + element Plus实现表格根据关键字合并行,并实现行的增删改操作

根据关键字合并表格 1.实现初始化表格2.实现添加班级与学生的功能3.添加的弹窗4.删除班级5.删除学生 首先看最终实现的效果 1.实现初始化表格 这里主要用到的是表格的span-method这个方法 <template><div class"main-page"><div class"flex-en…...

c++视觉处理---直方图均衡化

直方图均衡化 直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分布图像的像素值&#xff0c;以使图像的直方图变得更均匀&#xff0c;从而提高图像的视觉质量。在OpenCV中&#xff0c;您可以使用 cv::equalizeHist 函数来执行直方图均衡化。以下是 cv::equal…...

【LeetCode】2.两数相加

目录 1 题目2 答案2.1 我写的&#xff08;不对&#xff09;2.2 更正 3 问题 1 题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返…...

蜘蛛飞机大战

欢迎来到程序小院 蜘蛛飞机大战 玩法&#xff1a; 点击开始游戏&#xff0c;鼠标移动控制方向&#xff0c;可自由移动飞机打剁掉方飞机下落的子弹并打掉敌方飞机&#xff0c;三次生命&#xff0c;不同关卡不同奖励&#xff0c;快去闯关吧^^。开始游戏https://www.ormcc.com/pl…...

代码混淆界面介绍

代码混淆界面介绍 代码混淆功能包括oc&#xff0c;swift&#xff0c;类和函数设置区域。其他flutter&#xff0c;混合开发的最终都会转未oc活着swift的的二进制&#xff0c;所以没有其他语言的设置。 代码混淆功能分顶部的显示控制区域&#xff1a;显示方式&#xff0c;风险等…...

蓝桥杯每日一题2023.10.9

题目描述 成绩统计 - 蓝桥云课 (lanqiao.cn) 题目分析 学会使用四舍五入函数round #include<bits/stdc.h> using namespace std; int s1, s2; int main() {int n, x;cin >> n;for(int i 1; i < n; i ){cin >> x; if(x > 60)s1 ;if(x > 85)s2 ;…...

HTML5的新增表单元素

HTML5 有以下新的表单元素: <datalist> <keygen> <output> datalist datalist 元素规定输入域的选项列表。 datalist属性规定 form 或 input 域应该拥有自动完成功能。当用户在自动完成域中开始输入时&#xff0c;浏览器应该在该域中显示填写的选项&…...

如何在Firefox中配置HTTP?

在浏览器中配置HTTP是一个常见的需求&#xff0c;它可以让我们轻松访问需要的网站或保护个人隐私。本文将为您详细介绍如何在Firefox浏览器中配置HTTP应用&#xff0c;帮助您实现无缝的HTTP体验。无论您是初次接触HTTP还是有一定经验的用户&#xff0c;本文都能为您提供实用的操…...

Android组件通信——消息机制(二十六)

1. 消息机制 1.1 知识点 &#xff08;1&#xff09;掌握Message、Handler、Looper类的使用以及消息的传递&#xff1b; &#xff08;2&#xff09;可以通过消息机制动态取得信息&#xff1b; 1.2 具体内容 对于android的消息机制&#xff0c;我们主要要使用Java中线程的一…...

《进化优化》第4章 遗传算法的数学模型

文章目录 4.1 图式理论4.2 马尔可夫链4.3 进化算法的马尔可夫模型的符号4.4 遗传算法的马尔可夫模型4.4.1 选择4.4.2 变异4.4.3 交叉 4.5 遗传算法的动态系统模型4.5.1 选择4.5.2 变异4.5.3 交叉 4.1 图式理论 图式是描述一组个体的位模式&#xff0c;其中用*来表示不在乎的位…...

spring:详解spring MVC

spring MVC SpringMVC是一种基于Java的MVC&#xff08;Model-View-Controller&#xff09;Web开发框架&#xff0c;通过将业务逻辑、数据和界面分离&#xff0c;使得开发人员能够更高效地管理和维护代码&#xff0c;提高应用的可扩展性和可维护性。 SpringMVC核心概念 Contr…...

【Leetcode】207.课程表

一、题目 1、题目描述 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 p r e r e q u i s i t e s [ i ] = [ a i , b...

Ubuntu18.04中QT安装下载安装pcl和vtk以及使用过程中踩过的坑

一、先记录一下下载过程中踩过的坑 问题1&#xff1a;QVTKOpenGLNativeWidget和QVTKWidget 之前从来没有接触过QT中显示3D点云方面的知识&#xff0c;了解到可以用pcl&#xff0c;然后在网上各种找pcl下载的相关内容&#xff0c;想要在QT中显示出来&#xff0c;需要用到VTK&a…...

C++学习——对象数组、成员对象与封闭类

以下内容源于C语言中文网的学习与整理&#xff0c;非原创&#xff0c;如有侵权请告知删除。 一、对象数组 对象数组&#xff0c;即数组的每个元素都是某个类的对象。 1、对象数组中的每个元素都需要用构造函数初始化&#xff0c;具体哪些元素用哪些构造函数初始化&#xff0c…...

解锁机器学习-梯度下降:从技术到实战的全面指南

目录 一、简介什么是梯度下降&#xff1f;为什么梯度下降重要&#xff1f; 二、梯度下降的数学原理代价函数&#xff08;Cost Function&#xff09;梯度&#xff08;Gradient&#xff09;更新规则代码示例&#xff1a;基础的梯度下降更新规则 三、批量梯度下降&#xff08;Batc…...