javaer to go之基础

1、开始

我是一个javaer,最近空闲时间在学习golang。

度娘后,安装好Go环境和LiteIDE后,一开始我也没从基础开始看,而是想把现有的java项目改成是golang版本的。

原项目内容:

  1. socket模块接收下位机的数据
  2. 对协议数据进行解析
  3. 把协议数据解析后存进数据库
  4. web子项目

golang相比java,有很多很方便的特性。特别是并发与网络方面更是golang的卖点。所以我就直接找了个socket的例子开始模拟着实现项目的socket模块

2、第一个程序

server.go :

package socket

import (
    "fmt"
    "net"
    "strings"
)

func  StartServer() {
    service := ":3338"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    for {
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        fmt.Println("新连接:", conn.RemoteAddr().String())
        go handleConn(conn)
    }
}

func handleConn(conn net.Conn) {
    for {
        buffer := make([]byte, 1024)

        length, err := conn.Read(buffer)
        if err != nil {
            conn.Close()
        }

        if length > 12 {
            data := buffer[:length]

            switch data[11] & 0xff {
            case 0x80:
                //桌子
                fmt.Println("桌子")
            case 0x90:
                //椅子

            case 0xA0:
                //台灯

            default:
                //其它

            }

            //写数据

            //      conn.Write(data)
        }
    }

}

func isProtocol(data []byte) bool {
    if (data[0]&0xff) == 0xC0 && (data[len(data)-1]&0xff) == 0xC1 {
        return true
    }
    return false
}

func checkError(err error) {
    if err != nil {
        fmt.Println(err.Error())
    }
}

因为是第一篇笔记,也简单地说一下golang的基础语法。

对于一个javaer来说,或者一个有计算机语言基础的朋友来说,golang的语法看起来不会太困难。

3、包路径

像java一样,一开始我们为程序声明一个包路径

package socket

和java不一样的是,golang的包不是层叠式的。所以为了方便识别我们也可以为我们所有的项目放到一个父包下。

类似与java,我这里使用了一个letus.xyz的命名作为父包(文件夹)。这样其它的程序就能比较方便地找到server.go程序来调用。

如果想要构建一个程序,则包和包内的文件都必须以正确的顺序进行编译。包的依赖关系决定了其构建顺序。

属于同一个包的源文件必须全部被一起编译,一个包即是编译时的一个单元,因此根据惯例,每个目录都只包含一个包。

如果对一个包进行更改或重新编译,所有引用了这个包的客户端程序都必须全部重新编译。

4、包与库的导入

import (
    "fmt"
    "net"
    "strings"
)

和java相比,golang使用的这种方式进行导包和库看起来优雅多了。

当然,你也可以像java一样,一个一个地import

import "fmt"
import  "net"
import  "strings"

注意事项:

如果你导入了一个包却没有使用它,则会在构建程序时引发错误,如 imported and not used: os,这正是遵循了 Go 的格言:“没有不必要的代码!“。

当你导入多个包时,导入的顺序会按照字母排序。

如果包名不是以 . 或 / 开头,如 “fmt” 或者 “container/list”,则 Go 会在全局文件进行查找;如果包名以 ./ 开头,则 Go 会在相对目录中查找;如果包名以 / 开头(在 Windows 下也可以这样使用),则会在系统的绝对路径中查找。

导入包即等同于包含了这个包的所有的代码对象。

除了符号 _,包中所有代码对象的标识符必须是唯一的,以避免名称冲突。但是相同的标识符可以在不同的包中使用,因为可以使用包名来区分它们。

5、 函数

导入包和库之后,就是我们的程序主体了。当然,我们写程序的时候肯定是package之后就直接写程序主体,而包与库是到用到这个包内容的时候再导。

golang和c一样,是面向过程的函数式编程,而不是java那样的面向对象。

func  StartServer() {

}

func isProtocol(data []byte) bool {

    return false
}

func checkError(err error) {

}

可见性规则:

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )。

函数的基本结构:

func functionName(parameter_list) (return_value_list) {
   …
}

其中:

  • 参数:parameter_list 的形式为 (param1 type1, param2 type2, …)
  • 返回类型return_value_list 的形式为 (ret1 type1, ret2 type2, …)

golang的方法比java有意思的是它允许返回多个值。而它的参数表示形式与java也不一样,名字是放在类型的前面。

6、变量

service := ":3338"

:=是简短声明语法 ,表示声明并赋值。
或者你也可以用var来声明:

var service = ":3338"

var service string
service = ":3338"

简短声明法看起来更加优雅些。

7、常量

const (
    Unknown = 0
    Female = 1
    Male = 2
)

我们第一个程序没用到常量。常量是通过const来定义的。

常量的定义格式:

const identifier [type] = value

8、基本数据类型

  • int,Runes(注:Rune 是int 的别名)
  • int8 ,int16 ,int32 ,int64
  • byte ,uint8 ,uint16 ,uint32 ,uint64 (注:byte是uint8 的别名)
  • float32 ,float64 (没有float 类型)
  • bool
  • string
  • complex128,complex64

9、main函数

package main

import (
    "letus.xyz/socket"
)

func main() {
    socket.StartServer()
}

这里我们通过绝对路径letus.xyz主包找到socket包来调用程序。当然我们也可以相对目录导入。很明显,相对路径的方式不利于包的复用。

所以个人建议使用绝对路径来导包,毕竟思想上和java相似。

import (
    "../socket"
)

10、其它

golang的运算符与控制结构语句的使用基本和java的一样,但值得一提的是,golang的switch语法支持字符串的匹配。这是作为一个javaer经常想java也提供的一个特性。

switch field.Type().String() {
case "time.Time":
    v, _ := time.Parse("2006-01-02 15:04:05", s)
    field.Set(reflect.ValueOf(v))
}
时间: 2024-11-09 23:58:08

javaer to go之基础的相关文章

xcode-学习objective-c 基础教程遇到问题 例题03.06 word-length-3 编译出错

问题描述 学习objective-c 基础教程遇到问题 例题03.06 word-length-3 编译出错 #import int main(int argc, const char * argv[]) { FILE *wordFile = fopen ("/tmp/words.txt", "r"); char word[100]; while (fgets(*word,99,wordFile)) \这一行编译出现"Thread 1:EXC_BAD_AC

零基础如何自学UI设计?

  酸梅干超人:下面是我这几年经验的总结和思考,虽然我并不算是最出类拔萃的UI设计师,但也希望对新人有益. 第一点:学习准备--启蒙 学习一项技能,尤其是已经有一定沉淀并在各行各业有广泛应用的技能,就一定要对它先有充分的认知.在开始正式学习前,你需要花足够的经历去了解和查阅它的起源.发展.应用.未来.UI作为平面设计的一部分,再往上又从属与美术学这一大类.因此,首先要先去了解整个美术史的发展.从人类起源各个阶段中,美术经历了什么样的变化,在各自的时代发挥了什么作用,近代美术史又经历了哪些波折,平

.NET 2.0 基础类库中的范型——其他范型类

其他范型类.NET 2.0 基础类库对范型的应用当然并不仅限于范型集合和 Functional Programming.下面所列的范型类也都有其明确的设计目的和用途. Array在.NET 2.0中,Array 类扩充了对范型编程的支持.当然,Array类本身并不是范型类(出于兼容的考虑),而是提供了一系列支持范型的方法.除了前面提到的 Functional Programming 的支持外,Array 类还对以前很多基于 object 的方法提供了对应的范型版本,这样对值类型可以提高查找和排序

Grand Central Dispatch(GCD)编程基础

有过编程经验的人,基本都会接触到多线程这块. 在java中以及Android开发中,大量的后台运行,异步消息队列,基本都是运用了多线程来实现. 同样在,在ios移动开发和Android基本是很类似的一种模型. 但是很多时候,在应用开发中,我们会发现本身并没有自己编码去处理一些并发的事件,去开辟新的子线程等等. (虽然一般的调用sdk发起一个网络请求,系统都是会默认给你新起一个线程去处理的). 整个程序看上去基本就是在Main线程中执行. 确实也是这样的一种现象,因为我们基本都是在操作控件的布局,

Linux 系统应用编程——进程基础

一.Linux下多任务机制的介绍          Linux有一特性是多任务,多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的应用程序被称为一个任务.          多任务操作系统使用某种调度(shedule)策略(由内核来执行)支持多个任务并发执行.事实上,(单核)处理器在某一时刻只能执行一个任务.每个任务创建时被分配时间片(几十到上百毫秒),任务执行(占用CPU)时,时间片递减.操作系统会在当前任务的时间片用完时调度执行其他任务.由于任务会频繁地切换执行,因此给用户多

基础-关于Android在模拟器打开的首页跟在手机打开的首页不同

问题描述 关于Android在模拟器打开的首页跟在手机打开的首页不同 我是在网上下载一个别人已经写好的二维码扫描功能的项目,然后我在其基础上改变他的首页,然后在模拟器中能成功运行,并符合想象,可是一把apk拉到手机上安装时,又是原来的首页,有哪位大神能够帮忙解析一下吗? 解决方案 清除下浏览器缓存看看.二维码扫描是否正确.还有,对方网站是否根据ip判断的登录方式.

类别-Objective-C基础教程中一句话读不懂,求解!

问题描述 Objective-C基础教程中一句话读不懂,求解! 在第12章类别前边第一段中有:"当使用类方法stringWithFormatFor生成一个新类时,你新建的NSString类的子类无法返回." 解决方案 NSString实际上只是一个类簇的前台表示,因而无法为这样的类创建子类.在其他情况下,你也许可以创建子类但你使用的却是工具包或类库,因为又无法处理新类的对象.例如,当使用类方法stringWithFormatFor生成一个新的字符串时,你新建的NSString类的子类无

RESTful_基础知识

前言 本篇主要是RESTful的基础知识整理,主要是为了将要开始的Openstack架构主题做知识积累.理解好RESTful的设计思想无论是对学习Openstack架构还是Openstack Dashboard实现都是一件事半功倍的事情. RESTful REST(Representational State Transfer):是一种软件架构的设计风格,而不是一种标准.主要用于C/S架构的软件设计,也能很好的支持B/S架构,为软件设计提供了一组原则和约束条件,但这是原则和约束的条件均不具有标准

走上开放之路: ASP开发人员的J2EE基础(下)

相关文章:走上开放之路: ASP 开发人员的 J2EE 基础(上) ASP/COM 和 J2EE 应用程序模型 接下来研究不同的应用程序体系结构,您可以使用这些体系结构开发 J2EE 应用程序并将 其与相应的 ASP/COM 应用程序体系结构关联起来. 使用 Java Servlets 编程:基础知识 编写 Java Servlets 就可以对来自 URL 的请求进行可编程控制.典型的 servlet 调用 类似于以下步骤: 客户机向 Web 服务器发出请求,将 servlet 命名为 URL