从java入坑go

本文介绍了Go语言的主要优点,如运行速度快、内存占用小和并发特性,并对比了与Java的差异。Go中的错误处理通过函数返回的error判断,每个包仅能有一个main方法,依赖管理使用gomod。此外,文章还详细讲解了Go的基本语法,包括变量、常量、数组、切片、map、函数、结构体、接口和goroutine。Go的并发通过goroutine和channel实现,强调了无缓冲和有缓冲channel的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直从事Java相关的工作,最近学习了go语言,作为没有接触过C的菜鸟刚开始撸go的时候还是有点不适应,废话不多说直接进入主题。

一、go简介

go是Google开发的一种编译型静态语言,语法简单,支持并发,相对于其他语言go的优点:

1)运行速度:可直接编译成机器代码直接执行,而java代码需要JVM加载字节码解释成机器码;

2)占用内存:go语言占用内存很小,节省了很大的内存空间,更轻量;

3)为并发而生:并发过程中,不同于java中的线程,go通过协程goroutine来实现并发,goroutine非常轻量;

在学习过程中,感觉go不太友好的地方(因为刚接触没多久,可能存在误解):

1)异常处理:go中所有的错误信息都是通过函数返回的error是否为nil,如果为nil说明发送异常然后进行相关操作,不同于java中可以捕获,还可以抛不同类型的异常,感觉没有java中的灵活;

2)对于每个包中只能有一个main方法,这很坑,在前期学习go的时候,感觉创建了N个包;

3)如果想添加第三方依赖虽然有go mod,但是感觉没有java中类似maven、gradle方便

二、go的基本语法

先看个hello world感受一下go世界

package main

import "fmt"

func main() {
	fmt.Println("hello world")
}

package跟java一样有包的概念,不同的是java中的包名是包具体路径的名字,go中默认为main,表示当前是一个执行程序,可手动修改,如果修改后执行会报错。

package command-line-arguments is not a main package

import引入依赖库,其中fmt为包名,不能直接引入具体的文件,main()为主函数,程序的入口跟java一样,fmt.Println()打印hello world。

1、go中常用基本类型

布尔类型:bool

整型:int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64

浮点:float32、float64

字符:char

字符串:string

复数:complex64、complex128

int类型在32位系统上是int32,表示有符号32位整型即4字节,和java中的int一样,在64位是int64与java中long一样,go还提供了无符号uint类型

其他类型:

指针类型

数组类型

切片类型

结构体类型

channel类型

map类型

接口类型

2、go变量

go中四种变量声明方式

// 1、声明变量默认值为0
var a int

// 2
var b int = 100

// 3
var c = 100

// 4、该方式只能用于局部变量,其他三种可以设置全局变量
d := 100


// 同时给多个变量赋值
var aa, bb int = 100, 200
var cc, dd = 100, "dd"
var (
    ee int = 100
    dd bool = true
)

go中常量使用const关键字,可通过iota自增

const length int = 100

const (
    SUNDAY = iota  // iota默认为0,每行自增1
    MONDAY
    TUESDAY
    WEDNESDAY
    ...
)

3、go数组

// 固定数组
var myArray [4]int
for i := 0; i < len(myArray); i++ {
    fmt.Println(i, ": ", myArray[i])
}

输出结果:
0 :  0
1 :  0
2 :  0
3 :  0

myArray1 := [4]int{}
for index, value := range myArray1 {
   fmt.Println("index: ", index, "; value: ", value)
}

输出结果:
index:  0 ; value:  0
index:  1 ; value:  0
index:  2 ; value:  0
index:  3 ; value:  0


数组切片slice(无须设置数组长度)
slice1 := []int {1,2,3}

// 通过make关键字创建并且初始化数组
slice2 := make([]int, 3)

var numbers = make([]int, 3, 5) // 长度为3,容量为5,如果容量不够,会继续开辟5个空间

4、map

// map声明 1
var myMap1 map[string]string

//使用之前必须分配数据空间
myMap1 = make(map[string]string, 5)

// 2
myMap2 := map[string]string{
		"one": "java",
}

// 3
myMap3 := make(map[string]string, 5)

//赋值、更新
myMap1["one"] = "golang"

//删除
delete(myMap1,"one")

//遍历
for key, value := range myMap1 {
    fmt.Println("key: ", key, ", value: ", value)
}

5、函数、结构体

go中函数创建使用关键字func,defer在方法执行完成后执行,和java中的finally相似,可以同时写多个(存在多个defer时按照先写后执行的操作)。最后是先输出2222,在输出1111

func methodName(name string, age int) int {
	fmt.Printf("name: %s, name: %d", name, age)

    defer println("1111")
	defer println("2222")

	return age
}

go中使用struct关键字代替java中的类,go中没有private、protected、public等修饰词,通过变量名首字母来控制访问权限,如果是小写只能当前文件使用,如果是大写可以在同包不同的文件中使用

type Book struct {
    Title string
    auth string
}

// 声明对象
book := Book{Title: "golang", auth: "go"}

go中只需要在结构体中声明对象即可实现继承

type Animal struct {
    name string
    age int
}

type Bird struct {
    Animal
    fly string
}

func (bird *Bird) eat()  {
	fmt.Println(bird.Name, "eat bug")
}

//声明
bird := Bird{Animal{
		Name: "xique",
		Age:  1,
}, "flying"}

bird.eat();

除了继承,go也支持接口,不同于java,go无须强制实现,定义的结构体只需要全部实现所有接口中的方法即实现了该接口

type Animal interface {
    eat()
    sleep()
}

type Dog struct {
    name string
    color string
}

func (dog *Dog) sleep() {
    fmt.Println("sleep...")
}

func (dog *Dog) eat() {
    fmt.Println("eat...")
}

//声明
var animal Animal
animal = &Dog{}
animal.eat()

5、goroutine

go天生支持并发,goruntine也称为go协程

go func() {
    fmt.Println("start execute goroutine...")
}()

协程之间可通过channel进行通信,channel包括无缓冲和有缓冲两种方式

myChan <-:向管道中填充数据   <-myChan:从管道中取数据

func main() {
	myChan := make(chan string)
	go func() {
		fmt.Println("start execute goroutine...")
		myChan <- "end"     //(1)
	}()

	result := <- myChan  //{2}
	fmt.Println(result)
}

无缓冲区和有缓冲区的区别:

1)无缓冲区如果没有数据读操作会发送阻塞,比如上面的例子(2)会一直阻塞,直到(1)写操作完成后,才会执行,同样如果里面有数据了写操作也会阻塞,直到为空才会执行。

2)有缓冲如果没有数据读也会阻塞,但是如果里面有数据写不会阻塞直到写满后才会阻塞写操作;

//定义有缓冲区的chan
myChan := make(chan string, 3)

go中所有的错误处理都是通过函数返回来进行判断,如果返回的err!=nil说明发送错误,然后进行处理。

// 建立socket连接
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip, port))
if err != nil {
	fmt.Println("client dial error: ", err)
}

make与new的区别:

make只能创建slice切片、map、chan的初始化,make返回的是Type数据类型,new返回的是*Type指针类型,需要手动进行初始化。

// 使用new创建的map在使用之前必须要进行初始化
myMap := new(map[string]string)
*myMap = map[string]string{}
(*myMap)["a"] = "a"

// make创建的map已经完成初始化,可以直接使用
myMap2 := make(map[string]string)
myMap2["one"] = "golang"
是因为调用这个方法,报的上面这个错,请帮我分析根因,方法如下: def download_AG_app(self, driver, app_name, package_name): market_package = "com.huawei.appmarket" try: for i in range(2): driver.press_keycode(187) try: driver.find_element(By.ID, 'com.huawei.android.launcher:id/clear_all_recents_image_button').click() except: pass driver.press_keycode(3) except: pass time.sleep(10) driver.activate_app(market_package) time.sleep(10) self.click_element_with_swipe(driver, target_id='com.huawei.appmarket:id/enter_button', target_text='暂不安装') self.click_element_with_swipe(driver, target_id='android:id/button2', target_text='以后再说') # self.swipe_up(driver, swipe_times=3) driver.find_element(By.ID, 'com.huawei.appmarket:id/fixed_search_view').click() time.sleep(3) src_text = driver.find_element(By.ID, "com.huawei.appmarket:id/search_src_text") src_text.set_text(app_name) time.sleep(3) driver.find_element(By.ID, 'com.huawei.appmarket:id/hwsearchview_search_text_button').click() time.sleep(3) result1 = self.click_element_with_swipe(driver, target_id='com.huawei.appmarket:id/ItemTitle',target_text=f'{app_name}', max_swipe=5) # 可以在应用市场搜索到该应用 if result1 == True: time.sleep(5) # 场景1:应用未安装 result2= self.click_element_with_swipe(driver, target_id='com.huawei.appmarket:id/hwprogressbutton_percentage_text_view',target_text='安装') if result2 == True: time.sleep(90) result3 = self.click_element_with_swipe(driver,target_id='com.huawei.appmarket:id/hwprogressbutton_percentage_text_view',target_text='打开') # 应用规定时间内安装完成 if result3 == True: time.sleep(5) self.click_element_with_swipe(driver,target_id='com.android.permissioncontroller:id/permission_allow_button',target_text='允许') else: # 应用规定时间内未安装完成,点击暂停 driver.find_element(By.ID, 'com.huawei.appmarket:id/detail_download_button').click() self.go_back(driver, times=3) # 场景2:应用已存在 else: time.sleep(30) result4 = self.click_element_with_swipe(driver,target_id='com.huawei.appmarket:id/hwprogressbutton_percentage_text_view', target_text='打开') if result4 == True: time.sleep(5) self.click_element_with_swipe(driver, target_id='com.android.permissioncontroller:id/permission_allow_button',target_text='允许') else: pass else: failure_info = { "status": "fail", "app_name": app_name, "package_name": package_name, "reason": f"应用市场未找到应用:{app_name}(包名:{package_name})" } self.go_back(driver, times=3) return failure_info
最新发布
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值