天道酬勤,学无止境

Golang笔记之流程控制

一、条件语句

1.1if

if表达式的结果为true时执行语句块内代码

package main

import "fmt"

func main() {

    var flag bool = true

    if flag {

        fmt.Println("true")

    }

}

 

1.2if-else

if表达式结果为 true,则执行if语句块内代码,否则执行 else语句块内代码

package main

import "fmt"

func main() {

    var flag bool = false

    if flag {

        fmt.Println("true")

    } else {

        fmt.Println("false")

    }

}

 

1.3if-else if-else

当 if表达式结果为 true,则执行 if语句块内代码,否则依次从上到下判断 else if表达式结果,若结果为 true则执行对应语句块内代码并退出 if-else if-else语句,若 if和else if表达式均为 false,则执行 else语句块内代码

package main

import "fmt"

func main() {

    var ret int

    fmt.Print("请输入分数:")

    fmt.Scan(&ret)

    if ret >= 90 {

        fmt.Println("A")

    } else if ret >= 80 {

        fmt.Println("B")

    } else if ret >= 60 {

        fmt.Println("C")

    } else {

        fmt.Println("D")

    }

}

 

1.4、初始化子语句

可以在 if语句中初始化语句块内的局部变量,多个语句之间使用逗号(;)分隔

package main

import "fmt"

func main() {

    if flag := true; flag {

        fmt.Println("flag",flag)

    }

}

 

二、选择语句

2.1switch-case

swtich语句后面跟接变量,此时选择与变量相同的 case语句块执行并退出,若所有 case均不相同则执行 default语句块,case语句中可包含多个不同的值进行匹配

单值

    input := "yes"

    switch input {

    case "yes":

        fmt.Println("确认")

    case "no":

        fmt.Println("取消")

    default:

        fmt.Println("输入错误")

    }

多值

    input := "yes"

    switch input {

    case "yes","y":

        fmt.Println("确认")

    case "no","n":

        fmt.Println("取消")

    default:

        fmt.Println("输入错误")

    }

 

2.2switch-case 表达式

switch后不跟接变量,此时自上到下选择第一个表达式为 true case语句块执行并退出,若所有 case表达式均为 false,则执行 default语句块

    var ret int

    fmt.Print("请输入分数:")

    fmt.Scan(&ret)

    switch {

    case ret >= 90:

        fmt.Println("A")

    case ret >= 80

        fmt.Println("B")

    case ret >= 60:

        fmt.Println("C")

    default

        fmt.Println("D")

    }

 

2.3初始化子语句

可以在 switch语句中初始化语句块内的局部变量,多个语句之间使用逗号(;)分隔,注意初

始化表达式时后面的逗号(;)不能省略

初始化表达式

    switch ret := 80; {

    case ret >= 90:

        fmt.Println("A")

    case ret >= 80

        fmt.Println("B")

    case ret >= 60:

        fmt.Println("C")

    default

        fmt.Println("D")

    }

初始化值

    switch input := "yes"; input {

    case "y","yes":

        fmt.Println("yes")

    case "n","no":

        fmt.Println("no")

    default:

        fmt.Println("输入错误")

    }

 

2.4、fallthrough

switch-case默认执行 case语句后退出,若需要继续执行下一个 case语句块,可以在 case

语句块中使用 fullthrough进行声明

    var ret int

    fmt.Print("请输入分数:")

    fmt.Scan(&ret)

    switch ret := 80; {

    case ret >= 90:

        fmt.Println("A")

        fallthrough

    case ret >= 80

        fmt.Println("B")

    case ret >= 60:

        fmt.Println("C")

    default

        fmt.Println("D")

    }

 

三、循环语句

3.1for

for语句后有三个子语句分别为:初始化子语句,条件子语句和后置子语句

执行顺序为:

a) 初始化子语句

b) 条件子语句

c) 语句块

d) 后置子语句

e) b->c->d

f) …

g) 直到条件子语句为 false结束循环

    sum := 0

    for i := 0; i <= 100i++ {

        sum += i

    }

    fmt.Println(sum)

 

3.2breakcontinue 语句

break用于跳出循环,当条件满足则结束循环

continue用于跳过循环,当条件满足这跳过本次循环进行后置或条件子语句执行

    for i := 0; i <= 100i++ {

        if i == 60 {

            break

        }

        if i >= 50 {

            fmt.Println(i)

            continue

        }

    }

 

3.3、只有条件子语句的for

    sum := 0

    i := 1

    for i <= 100 {

        sum += i

        i++

    }

    fmt.Println(sum)

 

3.4、死循环

    sum := 0

    i := 1

    for  {

        if i > 100 {

            break

        }

        sum += i

        i++

    }

    fmt.Println(sum)

 

3.5for range 遍历

用于遍历可迭代对象中的每个元素,例如字符串,数组,切片,映射,通道等

针对包含 Unicode字符的字符串遍历是需要使用 for-range,range返回两个元素分别为字

节索引和 rune字符,可通过空白标识符忽略需要接收的变量

    //多维数组for range 遍历

    for ik := range a1 {

        for jv := range k {

            fmt.Printf("一维:%d 二维:%d  值:%d\n"ijv)

        }

    }

 

四、labelgoto

4.1goto跳转label

可以通过 goto语句任意跳转到当前函数指定的 label位置

    sum := 0

    i := 1

    START: //定义START标签

    if i > 100 {

        goto STOP //跳转到STOP标签

    } else {

        sum += i

        i++

        goto START 

    }

    STOP:

    fmt.Println(sum)

 

 

 

4.2breakcontinue跳转label

break和 continue后也可以指定 label用于指定跳出或跳过指定 label同层级的循环

    RESTART:

    for i := 1; i < 10i++ {

        for j :=1; j < 10j++ {

            if j == 3 {

                continue RESTART //跳过外层循环

            }

            if i == 5 {

                break RESTART //跳出外层循环

            }

            fmt.Println(i,j)

        }

    }

 来自于吴科老师《手撕go语言》 马哥go运维开发第四期

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Python之流程控制语句经典例题(3)
    例题 6.编写程序,生成10个随机数,每个元素的值介于1到100之间,并计算所有元素的和、平均值。 7.编写程序,根据输入的行列数值,生成相应的矩阵(其中元素为随机数)。 8.编写程序实现打印100以内的素数。 一、解析 这几个题都要导入random(随机)包 要生成随机数,要用到random.randint( )方法 random.randint(a,b) #函数返回数字 N ,N 为 a 到 b 之间的数字(a <= N <= b),包含 a 和 b。 第六个题目:通过random生成10个随机数,并求出和及平均值,这个题较为容易实现。 第七个题目:要再导入numpy包,利用numpy.zeros()方法创建矩阵 numpy.zeros(shape,dtype=float,order = 'C') #返回给定形状和类型的新数组,用0填充。 #shape 数组形状 #dtype 数据类型,可选 #order 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 关于numpy的用法可以参考菜鸟教程https://www.runoob.com/numpy/numpy-array-creation.html 第八个题目:打印100以内的素数。 题目的思想可以参考这一篇博客https://blog.csdn.net/cbjcry/article
  • 10 goroutine和channel
    文章目录 go并发编程概念goroutinechannel go并发编程概念 几乎所有的语言都支持并发编程。go也不例外,且轻量级并发编程(协程)是Golang的重要特性。 基本概念 进程:进程是程序在操作系统中的一次执行过程。是系统进行资源分配和调度的基本单位 线程:是进程的一个执行实例,是程序的最小执行单元,是比进程更小的能独立运行的基本单元。一个进程可以创建和销毁多个线程,一个程序至少有一个进程,一个进程至少包含一个线程 并发:多线程程序在单核上运行,就是并发,某一时刻只有一个线程在执行,多个线程轮流执行(每个线程轮流执行的时间很短,宏观上看好像是多个线程同时执行)。 并行:多线程程序也在多核上运行就是并行,某一时刻 有多个线程在执行。 Go线程和协程:一个GO线程上可以起多个协程(go特有的轻量级线程) 协程的特点:有独立的栈空间、共享程序堆空间、调度由用户控制 主线程是一个物理线程,直接作用在CPU上,是重量级的,非常消耗CPU资源。协程是从主线程开启的轻量级线程。一般语言不支持协程线程开多了资源消耗会很大,但是golang协程可以轻松开启数万个。 Golang可以设置程序运行的cpu数(1.8之后默认多核运行) num := runtime.NumCPU() runtime.GOMAXPROCS(num) fmt.Println("程序运行cpu数量:",num)
  • 【工作感悟】JVM虚拟机原理深入解析,安卓系列学习进阶视频
    写在前面 身边有不少去大厂面试的朋友,其中小金面试字节跳动的经历很有意义,在这里分享给大家。小金是末流211计算机专业大三本科生,前几天面试了字节跳动的广州Android开发实习生。下面是他的面试经历,还有一些他自己的经验。 1、MVVM架构模式概览 这是使用MVVM架构模式+Kotlin协程+JetPack(ViewModel+LiveData)+Retrofit的架构,实现WanAndroid登录接口的小DEMO,后续会慢慢完善WanAndroid客户端 1、ViewModel 为了从界面控制器Activity/Fragment逻辑中分离出视图View数据所有权,架构组件为界面控制器提供了 ViewModel 辅助程序类,该类负责为界面准备数据。在配置更改期间会自动保留 ViewModel 对象,以便它们存储的数据立即可供下一个 Activity 或 Fragment 实例使用。 2、LiveData LiveData 是一种可观察的数据存储器类,具有生命周期感知能力,意指它遵循其他应用组件如 Activity、Fragment 或 Service 生命周期,可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。LiveData 对象通常存储在 ViewModel 对象中,并可通过 getter 方法进行访问。 3、Kotlin协程 协程依附在线程上
  • 2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?外部协程奔溃,内部协程还会执行
    2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?外部协程奔溃,内部协程还会执行吗?外部协程执行结束的时候,如何让内部协程也停止运行?golang原生提供的包里,让内部协程停止运行,如何实现?福哥答案2021-03-11:1.外部协程和内部协程没关系。2.如果程序不奔溃,不会影响内部协程继续执行。如果没做特殊处理,整个程序会奔溃。3.三种方式:共享变量作为标志位,通道,上下文context。这三种方式均是协作式中断,不是抢占式。对于程序员,是无法实现抢占式中断的。 如果能实现抢占式,请发代码,谢谢。 代码用golang编写,代码如下: package main import ( "context" "fmt" "time" ) func main() { input := 0 for { fmt.Println("1.标志位方式") fmt.Println("2.通道方式") fmt.Println("3.上下文方式") fmt.Println("4.退出") fmt.Println("请输入数字:") fmt.Scanf("%d", &input) switch input { case 1: go outer1() case 2: go outer2() case 3: go outer3() default: return } time.Sleep
  • 带你一步一步深入Handler源码,手慢无
    关于面试题 打个比方,如果把找工作理解成考大学,面试就是高考,市面上的“真题”就是模拟试卷。我们会很容易倾向于在面试前寻找对应公司的面试“真题”,重点准备,期待“押题”成功。但实际上,即使面试同一家公司,它会有不同部门,不同业务线,不同面试官,即使遇到同一面试官,他也不一定就每次考察完全一样的内容。想想高考中那些考的好的同学,他们肯定不是靠“押题”才能取得好成绩吧,他们大多靠的是平常积累及对知识点灵活掌握,那面试也一样啊。执着于搜题,把面试题当做重点进行“复习”,还不如自己划出“考纲”,各个知识点逐一检查掌握情况,复习的更全面呢。 我对于面试题的看法一直是相对保守的,这类文章一般只是内容搬运,它会存在一些偏差和误读,最重要的那就是几道题往那一扔,并没有产出有价值的东西。这也是为什么我上篇面试总结,会加了一些面试技巧,整理面试题时,也没提他们是出自哪家公司,就是不希望大家把题目区别看待。 说了这些并不是说面试题没用啊,而是希望大家不要迷信面试题,更多地去关注那些有质量有深度的技术文章。面试考核的是知识点而不是具体的某些题目,面试题的作用在于,衡量我们的知识掌握情况,便于我们查漏补缺,越说越像是针对一次“考试”了。 一、Java 知识梳理 Java&Android 基础知识梳理(0) - Java 基础知识大纲 Java&Android 基础知识梳理(1) - 注解 Java
  • 一线互联网移动架构师设计思想解读开源框架!成功定级腾讯T3-2
    缘起 字节跳动的音视频面准备了半个月的样子,当时投了很多厂,但是主要目标还是进字节,但是万万没想到,居然一面就没了下文(一开始觉得起码能撑到个二面,三面,所以有些措不及防……) 在期间,也陆陆续续收到了其他公司的几个offer,但是都是些小公司,没有达到预期目标。于是后面干脆闭关了几天专心复习,刷题,准备二战。 大概闭关复习了半个月,又投了字节,同期还投了腾讯等几个大厂还有一些小厂。 面了几个就收到了腾讯的面试通知,就先去了腾讯,没想到一路“过五关斩六将”直接拿下了offer。 后面字节也约了面试,但是腾讯那边HR问了一下我是不是还有别的面试,我如实说了字节那边,然后他们提了待遇,我感觉腾讯这边还是很有诚意的,又因为字节那边还没有定下来,就答应去腾讯那边了。 一、Java 知识梳理 Java&Android 基础知识梳理(0) - Java 基础知识大纲 Java&Android 基础知识梳理(1) - 注解 Java&Android 基础知识梳理(2) - 序列化 Java&Android 基础知识梳理(3) - 内存区域 Java&Android 基础知识梳理(4) - 垃圾收集器与内存分配策略 Java&Android 基础知识梳理(5) - 类加载&对象实例化 Java&Android 基础知识梳理(6) - 字节输入输出流 Java&Android 基础知识梳理(7) -
  • Golang学习笔记(2)---go语言基本类型
    布尔型:bool长度1字节取值范围:true,false注意:不可以用数字代表true或false整型:Int根据平台可能为32为或64位 8位整型:int8/uint8长度:1字节取值范围:-127~127,0~255byte 字节型 其实就是 uint8的别名 16位整型:int16/uint16长度:2字节取值范围:-32768~32768,0~65535 32位整型:int32/uint32长度:4字节rune就是int32的别名 浮点型:float32/float64长度:4字节/8字节小数位:float32精确到小数点后7位,float64精确到小数点后15位保存指针的uintptr类型,根据平台来分为32位或64位其他类型:array struct string引用类型:map slice chan(并发会使用到)接口类型:interface函数类型:func (因为函数可以复制给变量的)类型零值: 零值并不等于空置,而是当变量被声明为某种类型后的默认值,通常情况下值的类型都为0,bool为 false,string为空字符串,数组的话和数组类型的零值保持一致 [2]int,则数组的初始值为[0 0]类型别名: 使用type对类型进行别名 这样是可以的,但是不建议这样使用,type定义一些其他的别名(type byte64 int64),来使代码可读性更强
  • 做了6年的Android,Android权限处理,已拿offer
    前言 再过几个月就到了毕业季,越来越多的00后就会加入到求职找工作的大潮中,而身为30岁的你是否感到了彷徨与压力……是否也能成为新机遇下的弄潮儿。 1、MVVM架构模式概览 这是使用MVVM架构模式+Kotlin协程+JetPack(ViewModel+LiveData)+Retrofit的架构,实现WanAndroid登录接口的小DEMO,后续会慢慢完善WanAndroid客户端 1、ViewModel 为了从界面控制器Activity/Fragment逻辑中分离出视图View数据所有权,架构组件为界面控制器提供了 ViewModel 辅助程序类,该类负责为界面准备数据。在配置更改期间会自动保留 ViewModel 对象,以便它们存储的数据立即可供下一个 Activity 或 Fragment 实例使用。 2、LiveData LiveData 是一种可观察的数据存储器类,具有生命周期感知能力,意指它遵循其他应用组件如 Activity、Fragment 或 Service 生命周期,可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。LiveData 对象通常存储在 ViewModel 对象中,并可通过 getter 方法进行访问。 3、Kotlin协程 协程依附在线程上,可以实现顺序编写异步代码,自动进行线程切换
  • Golang学习笔记(3)---go语言变量、常量的定义及赋值
    单个变量的赋值与声明变量的声明格式:var <变量名称> <变量类型>变量的赋值格式:<变量名称> = <表达式>声明的同时赋值:var <变量名称> [变量类型] = <表达式><变量名> := <变量值> --->只能在函数体内使用多个变量的复制与声明全局变量的声明可以使用var()的方式简写全局变量的声明不可以省略var,但可使用并行的方式所有变量都可以使用类型推断并行方式的声明:var a,b,c,d int=1,2,3,4函数体内:a,b,c,d :=1,2,3,4空白符_ 使用空白符,来对某个返回值,进行忽略变量的类型转换Go中不存在隐式转换,所有类型转换必须显式声明 -->保证了go是一个类型安全的语言 转换只能发生在两种相互兼容的类型之间 格式为: <变量A> [:] type变量A (变量B)var a float32 = 1.1 b := int(a) 由于浮点型到整型的转换只是一个精度的丢失,这种是可以进行转换的 var a bool = true b := int(a) 该表达式无法通过编译,因为类型不兼容,所以不能进行相互转换注意:在对int型转换为string型时,string(),表示把变量a转换为string格式,因为计算机中存储的任何东西本质上都是由0和1表示的数字,因此此函数自然的认为我们需要的是用数字65表示的文本(A)
  • go 语言知识点整理01
    1. go语言中切片的扩容机制是什么? 如果切片的容量小于1024个元素,那么扩容的时候slice的cap就在当前容量的基础上翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加当前容量的四分之一。 如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。 即大致可以表述如下: 当向切片中添加数据时,如果没有超过容量,直接添加,如果超过容量,自动扩容(成倍增长) 当超过容量,切片指向的就不再原来的数组,而是内存地址中开辟了一个新的数组. 2. 在go语言中,new和make的区别? new 的作用是初始化一个指向类型的指针(*T) new函数是内建函数,函数定义:func new(Type) *Type 使用new函数来分配空间。传递给new 函数的是一个类型,不是一个值。返回值是 指向这个新分配的零值的指针。 make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。 make函数是内建函数,函数定义:func make(Type, size IntegerType) Type · 第一个参数是一个类型,第二个参数是长度 · 返回值是一个类型 make(T, args)函数的目的与new(T
  • Spring Cloud 学习笔记十五:搭建微服务工程之Knife4j 介绍及使用
    目录 Knife4j 介绍及使用 Knife4j 介绍及使用 Knife4j的前身是swagger-bootstrap-ui,前身swagger-bootstrap-ui是一个纯swagger-ui的ui皮肤项目。具体介绍见官方文档 https://doc.xiaominfo.com/knife4j/documentation/description.html 。 在pom.xml中引入 Knife4j 的依赖包,代码如下: <!-- knife4j导出swagger文档 --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency> 在 Swagger3Config配置类添加 @EnableKnife4j注解: @Configuration @EnableOpenApi @EnableKnife4j public class Swagger3Config { ... } 重启服务,访问 http://localhost:8081/doc.html,可以看到界面。 增强模式 Knife4j 自 2.0.6 版本开始,将目前在 UI
  • HAL学习笔记-4 通用输入输出GPIO
    目录 一、GPIO概述基本概念 二、GPIO模块的电路结构与功能描述工作模式分类输入模式输入配置 输出模式输出配置推挽输出开漏输出 模拟模式模拟配置 复用模式复用配置 用法总结输入模式模拟模式输出模式复用模式 三、GPIO模块的常用寄存器介绍GPIO端口模式寄存器(GPIOx_MODER)GPIO端口输出类型寄存器(GPIOx_OTYPER)GPIO端口输出速度寄存器(GPIOx_OSPEEDR)GPIO端口上拉/下拉寄存器(GPIOx_PUPDR)GPIO端口输入数据寄存器(GPIOx_IDR)GPIO端口输出数据寄存器(GPIOx_ODR)GPIO端口置位/复位寄存器(GPIOx_BSRR) 四、基于寄存器方式控制GPIO1.利用指针访问单个寄存器地址转换方法寄存器宏定义例程开发1)新建MDK工程2)新建源文件并编写用户代码3)编译下载 2.利用结构体指针访问寄存器组寄存器组宏定义芯片头文件例程开发 四、基于HAL库方式控制GPIO1. 目标选择2. 基础配置1)选择时钟源2)配置调试接口 3.引脚分配4.外设配置5.时钟配置6.工程配置7.生成工程8.程序编写 一、GPIO概述 GPIO是通用输入/输出(General Purpose I/O)的简称,主要用于工业现场需要用到数字量输入/输出的场合,例如: 输出功能:继电器,LED,蜂鸣器等的控制输入功能:传感器状态
  • golang学习笔记-func函数
    函数function - Go函数不支持 嵌套、重载和默认参数 - 但支持以下特性: 无需声明原形、不定长变参、多返回值、命令返回值参数、匿名函数、闭包 - 定义函数使用关键字func,且大括号不能另起一行(所有有大括号的均遵循此原则) - 函数也可以作为一种类型的使用,直接赋值给变量(匿名函数) 定义一个函数 格式:func name( 传入的变量1 类型,变量2 类型 ) [ 返回变量 类型,变量 类型 ]{ } - 传入的变量可以没有,也可以使多个 - 当传入的变量类型相同时,可以全部省略只留最后一个 func a(a,b,c int) {} - 返回值可以有多个,返回值类型相同,也可以只留最后一个,其中返回变量名称可以省略,省略的话,就需要每返回一个写一个变量的类型了,如果指定了返回某个局部变量,那么这个变量就已经被定义,那么在函数体内即可直接使用。 - 不指定返回变量名称,那么需要在函数尾部写入 return 变量1,变量2, 如果指定了返回的变量名,那么只需要写上return即可。 - 传入的参数个数,也可以不定(不定长变参),使用...来表示,在函数体内存储这些数据的类型为slice func A(a ...int) -->...int必须放在最后 - 如果传入的值有1个string,有n个int,那么只能 fun A(b string, a ...int
  • mmkv缺点,腾讯3轮面试都问了Android事件分发,最强技术实现
    Android开发前景怎么样? 很多人说Android开发前景越来越差了 我觉得这个回答是片面的 首先Android应用开发前景差是在最近两年出现的,也就是从2018开始,从那时起移动端的程序员已经慢慢出现供大于求的局面,本人作为移动端开发,深知这一点。 然而也必须说明一点,不论是Android开发还是iOS开发,虽然都出现了相关的程序员供大于求的情况,但市场仍然是有需求的,特别是对资深的开发人员及拥有相关底层开发知识的应用程序员市场及发展还是很多的;这里所讲的就业难都是相对于初级开发人员。 为什么会在18年出现应用端就业难?这是由于在前几年App风盛行,那几年只要是个和互联网的公司要是没个自己的App那都不好意思叫互联网公司,所以一般的互联网公司成立之初就会着手开发自己的App,不管是否是刚需,但市场终究是严峻的;App虽然好,能快速开展本公司的业务,但App的运营成本还是很高的,一个App在早期就开发团队来说一般都是需要至少Android开发一人,iOS开发一人,后台开发2人以上,还有UI及产品等等,当然最主要的问题是一般的公司对于这种模式都会面临回报周期长的问题,App开发完了还面临着推广的问题,市场抢占不了,也许之前的都会付之东流。于是在早期很多学校特别是培训机构就针对市场推出了应用端的培训课程,短到三个月长到半年的课程,于是乎每一个月都会有成千上万的应用端走向市场
  • 构建微服务的十大 Golang 框架和库
    CLI 命令 (spf13/cobra) 你想生成一些 CLI 命令吗? Cobra 既是一个创建强大的现代 CLI 应用程序的库,也是一个生成应用程序和命令文件的程序。 我使用这个库来管理命令应用程序,执行 runner 应用程序,初始化配置,并启动 Rest API。 基于 Cobra 的应用组织结构: ├── app │ ├── main.go │ ├── cmd │ └── root.go 在 app/main.go 中: package main import ( "app/cmd" ) func main() { cmd.Execute() } 在 app/cmd/root.go 中: package cmd var rootCmd = &cobra.Command{ Use: "hugo", Short: "Hugo is a very fast static site generator", Long: `A Fast and Flexible Static Site Generator built with love by spf13 and friends in Go. Complete documentation is available at http://hugo.spf13.com`, Run: func(cmd *cobra.Command, args
  • Golang笔记之基本数据类型
    1、布尔类型布尔类型用于表示真假,类型名为bool,只有两个值true和false,占用一个字节宽度,零值为false var flag bool = true flag1 := false fmt.Println(flag,flag1)常用操作逻辑运算: 与(&&) 只有左、右表达式结果都为true,运算结果为truefmt.Println(flag&&true,flag1&&true) PS D:\goProject\day01> go run bool.go true false逻辑运算: 或(||) 只要左、右表达式有一个为true,运算结果为truefmt.Println(flag||true,flag1||true,flag1||false) PS D:\goProject\day01> go run bool.go true true false 逻辑运算: 非(!) 右表达式为true,运算结果为false;右表达式为false,运算结果为truefmt.Println(!flag,!flag1) PS D:\goProject\day01> go run bool.go false true关系运算 等于(==) 和不等于(!=)fmt.Println(flag == true, flag1 == true) PS D:\goProject\day01> go
  • Golang的context包详解
    context 包说明 说明:本文的用到的例子大部分来自context包。 概述 context 包定义了Context接口类型,它可以具有生命周期、取消/关闭的channel信号、请求域范围的健值存储功能。因此可以用它来管理goroutine 的生命周期、或者与一个请求关联,在functions之间传递等。 每个Context应该视为只读的,通过WithCancel、WithDeadline、WithTimeout和WithValue函数可以基于现有的一个Context(称为父Context)派生出一个新的Context(称为子Context)。其中WithCancel、WithDeadline和WithTimeout函数除了返回一个派生的Context以外,还会返回一个与之关联的CancelFunc类型的函数,用于关闭Context。 通过调用CancelFunc来关闭关联的Context时,基于该Context所派生的Context也都会被关闭,并且会将自己从父Context中移除,停止和它相关的timer。如果不调用CancelFunc,除非该Context的父Context调用对应的CancelFunc,或者timer时间到,否则该Context和派生的Context就内存泄漏了。 可以使用go vet工具来检查所有control
  • Go语言基础(一)
    一 简介 1 定义 Go 是一种开源的程序设计语言,它意在使得人们能够方便地构建简单,可靠,高效的软件。 2 产生原因 1 计算机硬件技术更新频繁,性能提高很快,目前主流编程语言发展落后,不能合理利用多核CPU优势来提高系统性能2 软件设计复杂度高,维护成本大3 C/C++编译速度过慢,需要解决提高速度 3 历史 Go是从2007年末由 Robert griesemer,rob pike,ken thompson 主持开发,后来加入了Ian Lance Taylor,Russ Cox,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本,现在Go完全开放。2015 年发布了Go 1.5 版本,完全移除了C代码 4 go 语言特点 1 继承C很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等 2 引入包的概念,用于组织程序结构,go语言中一个文件都要属于一个包,而不能单独存在 3 垃圾回收机制,内存自动回收,不需要开发人员管理,C需要 4 天然并发原因:A 从语言层面支持病啊,实现简单B goroutine轻量级线程,可实现大并发处理,高效利用多核特性 C 基于CPS并发模型实现 5 吸收了管道通信机制,形成Go语言特有的管道channel,通过管道,实现了不同goroute之间的互相通信 6 函数返回多个值 7 新的创新,切片,延时执行等特性
  • 手撸golang GO与微服务 net.rpc之2
    手撸golang GO与微服务 net.rpc之2 缘起 最近阅读 [Go微服务实战] (刘金亮, 2021.1) 本系列笔记拟采用golang练习之 gitee: https://gitee.com/ioly/learning.gooop net/rpc 微服务中的进程间通信概述 对于进程间通信的技术,开发者有多种选择。 可以选择基于同步通信的通信机制,比如HTTP RESTful; 也可以选择基于异步通信的方式,Go语言提供了标准的net/rpc包以支持异步。 远程过程调用协议(Remote Procedure Call Protocol, RPC), 是一种通过网络从远程计算机程序上请求服务, 而不需要了解底层网络技术的协议。 目标(Day 2) Day 1的rpc测试是短连接,频繁dial和close非常影响吞吐,改为长连接版本看看 设计 TimeConnection:封装rpc.dial以提供长连接的rpc.Client句柄。 rpc.Client.Call方法是并发安全的, 因此允许我们使用共享的长连接。 ITimeClientV2: 时间客户端接口 tTimeClientV2:时间客户端的实现, 持有长连接的rpc.Client句柄,进行远程GetTime调用 单元测试 common.go,封装单元测试的通用代码 package net_rpc import
  • apk优化工具,分析Android未来几年的发展前景,赶紧收藏!
    前言 这是“拔剑金九银十”的第二篇文章,本文主要针对3年以上的Android开发者进阶面试中高级开发工程师而整理。 希望可以对你们有所帮助。不多废话,进入正题。 目录: Java中高级 计算机网络 Android高级面试—性能优化 Android优秀第三方库 Android framework相关 其他Android高频面试题 组件化 1.1 组件化初衷 APP版本不断的迭代,新功能的不断增加,业务也会变的越来越复杂,维护成本高。业务耦合度高,代码越来越臃肿,团队内部多人协作开发困难。Android项目在编译代码的时候电脑会非常卡,又因为单一工程下代码耦合严重,每修改一处代码后都要重新编译打包测试,导致非常耗时。方便单元测试,改动单独一个业务模块,不需要着重于关注其他模块被影响。 1.2 什么是组件化 组件化就是将一个app分成多个Module,如下图,每个Module都是一个组件(也可以是一个基础库供组件依赖),开发的过程中我们可以单独调试部分组件,组件间不需要互相依赖,但可以相互调用,最终发布的时候所有组件以lib的形式被主app工程依赖并打包成一个apk。 1.3 组件化优势 组件化就是将通用模块独立出来,统一管理,以提高复用,将页面拆分为粒度更小的组件,组件内部除了包含UI实现,还包含数据层和逻辑层。每个工程都可以独立编译、加快编译速度,独立打包。每个工程内部的修改