golang学习-包、指针和内存分配

package 包名约定使用小写字符。包中的函数名以大写字母开头的是可导出函数,小写字母是私有函数。这个规定同样适用于新类型、全局变量。 当包导入(通过import)时,包名成为了内容的入口。在 import "bytes" 之后,导入包的可以调用函数bytes.Buffer。任何使用这个包的人,可以使用同样的名字访问到它的内容,因此这样的包名是好的:短的、简洁的、好记的。 根据规则,包名是小写的一个单词;不应当有下划线或混合大小写。由于每个人都可能需要录入这个名字,所以尽可能的简短。不要提前考虑冲突。 包名是导入的默认名称。 在Go中使用混合大小写MixedCaps或者mixedCaps,而不是下划线区分含有多个单词的名字。 包文档: 每个包都应该有包注释,在package 前的一个注释块。对于多文件包,包注释只需要出现在一个文件前,任意一个文件都可以。 包注释应当对包进行介绍,并提供相关于包的整体信息。这会出现在go doc生成的关于包的页面上,并且相关的细节会一并显示。 每个定义(并且导出)的函数应当有一小段文字描述该函数的行为。 常用包:http://golang.org/pkg/ 指针 go有指针,没有指针运算。一个新定义的没有指向的指针值为nil。
package main
import "fmt"

func main(){
var p *int
fmt.Printf("%v\n",p)
fmt.Printf("%T\n",p)
var i int
p = &i
fmt.Printf("%v\n",p)
*p =8
fmt.Printf("%v\n",*p)
}
结果: *int 0x10dd0018 8 *p++,表示(*p)++,先获取指针指向的值,然后加一。 内存分配 使用new分配内存 new(T)分配了零值填充的T类型的内存空间,返回其地址,一个*T类型的值。返回一个指针,指向新分配的类型T的零值。 用make分配内存 make(T,args)只能创建slice,map和channel,并且返回一个有初始值(非零)的T类型,不是*T.原因是指向数据结构的引用在使用前必须被初始化。 v := make([]int,100) 定义自己的类型
type person struct {
    name string
    age int
}

var P person
P.name = "Tom" // Assign "Tom" to P's name field.
P.age = 25 // Set P's age to 25 (an int).
fmt.Println("The person's name is %s", P.name)
P是一个person类型的变量。
package main
import "fmt"

type person struct{
    name string
    age int
}

func main(){
    a := new(person)
    a.name = "wang"
    a.age = 42
    b := person{"Tom",11}
    c := person{"rose",44}
    fmt.Printf("%v,%v,%v",a,b,c)
}
字段名字大写,可以导出,可以在其他包使用。小写则不可以。
Read more...

下载视频的工具网站

先上链接:http://kej.tw/flvretriever 用法:输入视频地址,就会出现不同格式的下载地址。已经验证youtube,不过需要你下载一个文件、然后打开赋值到输入框中。 在邮件列表看到有求助下载学习视频,我想帮忙下载,也造福我们大陆人。不想下载工具,也不想安装firefox插件,于是找到这么个网站,稍微记录下。
Read more...

golang学习笔记--函数

函数 golang作用域,定义在函数外的变量是全局的,函数内部定义的变量是局部的。如果一个局部变量和一个全局变量有相同的名字,在函数执行的时候,局部变量将覆盖全局变量。
package main
var a=6
func main(){
p()
q()
p()
}

func p(){
println(a)
}
func q(){
    //a := 5//定义变量
    a = 5//变量赋值
    println(a)
}
当在函数内定义是,输出656,而赋值为655. 局部变量仅在定义它的函数时有效。
package main
var a int
func main(){
    a=5
    println(a)
    f()
}

func f(){
    a := 6
    println(a)
    g()
}
func g(){
    println(a)
}
输出565 多值返回。 教程上有趣的例子:
package main

func nextInt(b []byte, i int) (int, int){
    x :=0
    for ; i

定义一个函数,传递一个byte数组和一个位置i,返回两个int类型。

看到golang的格言: 用更少的代码做更多的事

延迟代码defer。
在defer后指定的函数会在函数退出前调用。

func ReadWrite() bool{
file.Open("file")
//do something
if failureX{
file.Close()
return false
}
if failureY{
file.Close()
return false
}
file.Close()
return true
}
可以用defer修改为:
func ReadWrite() bool{
file.Open("file")
defer file.Close()
//do something
if failureX{
return false
}
if failureY{
return false
}
return true
}
函数在退出前会执行file.Close() 延迟的函数是按照后进先出的顺序执行。
for i:=0;i<5;i++{
defer fmt.Print("%d",i)
}
defer可以修改返回值。
package main
func f() (ret int){
    println(ret)
    defer func(){
        ret++
    }()
    return 0
}
func main(){
    println(f())
}
将输出1,ret是一个int型的命名返回值,这个不要看错了。 变参 例子代码:
package main

func myfunc(arg ...int){
    for _,n := range arg{
        println(n)
    }
}
func main(){
    myfunc(1,2,3,4,5)
}
将打印所有参数。arg ...int说明这个函数接受不定数量的参数。参数类型全部是int。在函数体中,变量arg是一个int类型的slice。 函数作为值
package main
import "fmt"
func main(){
    a := func(){
        println("hello")
    }
    a()//
    fmt.Printf("%T",a)
}
先定义一个匿名函数,赋值给a,然后调用函数a(),下面语句是输出a的类型。 接受函数作为参数的函数 回调 Panic和Recover golang没有像Java那样的异常机制:不能抛出异常。作为替代,使用panic和recover机制。这要作为最后手段使用。 没看懂。。。
Read more...

golang笔记-array、slices和map

array array由[n]定义,n标示array长度,type是类型。 var arr [10]int arr[0] = 42 arr[1] = 13 当向函数内传递一个数组的时候,会获得一个数组的副本,而不是数组的指针。 声明数组时,必须在方括号内输入一些内容:数字或者三个点。三个点,go会自动统计元素个数。 a:= [2][2]int{[2]int{1,2},[2]int{3,4}} a:= [2][2]int{[...]int{1,2},[...]int{3,4}} 或者 a:= [2][2]int{{1,2},{3,4}}//当元素复合声明的类型和外部一致时 slice slice与数组区别,slice可以怎讲啊长度,slice总是指向底层的一个array。slice是指向array的指针。slice是引用类型的,当一个函数需要一个slice参数,函数内对slice修改。slice总是与一个固定长度的array承兑出现。 int:var array[m]int //创建一个m个元素的array。 slice := array[0:n] 几个长度 len(slice)==n cap(slice)==m len(array)==cap(array)==m map 定义map的方法:map[] monthdays := map[string]int{ "Jan":31,"Feb":28, } 最后一个逗号是必须的。 先写到这里了,准备粗略把教程看完。原因是现在用golang学习语法时,太麻烦了。每次都是修改源文件--打开shell--go run,感觉要受不了了,决定写一个像python在shell里一样方便的东西学习语法。
Read more...

golang学习-变量和类型

放在同一行的多个语句,必须用分号分隔。 变量的类型在变量名后面。 var a int var b bool a = 15 b = false 等价: a := 15 b := false 多个var声明可以成组。 var{ x int b bool } 同样适用于const和import。 相同类型的多个变量可以在一行内完成声明: a,b := 20,16 一个特殊的变量名_(下划线),任何赋值给他的值都被丢弃。 _,b := 34,35 golang编译器对声明却未使用的变量报错。 变量名 declared and not used。 布尔类型: true和false 数字类型: int ,根据硬件决定长度。32位硬件是32位,64位为64.也可以明确其长度,完整的整数类型表; int8,int16,int32,int64 byte, uint8,uint16,uint32 uint64.byte是uint8的别名。 浮点型有float32,float64(没有float类型)。 64位的整数和浮点数都是64位的,即便是在32位的架构上。这些类型全部独立,混合这些类型向变量赋值引起编译器错误。 常量:只能是数字、字符串和布尔值。可以使用iota生成枚举值。 const( a = iota b = iota ) 第一个iota表示0,因此a为0,当iota再次进行新的一行使用时,值增加1,b的值为1. 可以省略重复的iota。 const( a = iota b ) 字符串: string s := "hello world!" go中字符串是UTF-8的由双引号包裹。单引号表示一个字符,不是string。一旦给变量赋值,字符串就不能修改了。 一下做法非法: var s string = "hello" s[0] = 'c' go中实现的方法:
s := "hello"
c := []byte(s) //转换s为字节数组
c[0] = 'c' //修改数组
s2 := string(c) //创建新字符串
多行字符串
//错误写法:
s := "starting part"
    + "ending part"
//会被转换成
s := "starting part";
    + "ending part";
//正确写法
s := "starting part" + 
    "ending part"
//另一种写法,使用`反引号作为原始字符串符号
s := `starting part
    ending part`
//最后一个s将包含换行。在原始字符串标识中的值字符是不转义的。
//可以写一个例子,将上面修改为:
s := `starting \n part
ending part`
fmt.Printf("%s",s)
//会发现starting和part间没有换行而是‘\n’
rune :int32别名。用UTF-8进行编码。需要遍历字符串中的字符。可以循环每个字符。 复数:变量类型是complex128(64位虚数部分),complex64(32位虚数部分) 复数写为re+imi,re是实数部分,im虚数部分。 var c complex64 = 5+5i 错误:error。var a error定义a为一个error,a的值为int。
Read more...

golang在windows安装,vim配置,helloworld笔记

安装过程很简单,官网有详细文档:http://golang.org/doc/install#windows 前几天还记得可以访问,今天不行了。汗,我直接下载的zip file 解压到c盘,将c:\go\bin添加到系统变量中,安装完成了。。。 下面说说vim的golang配置,下载地址:https://github.com/jnwhiteh/vim-golang,在直接拖到Vim\vimfiles,搞定。官方给的应该和这个一样,没看,http://golang.org/misc/。 上hello world代码:没高亮(决定改掉他)
package main

import "fmt"

func main(){
fmt.Printf("hello world~")
}
编译:go build hello.go 运行: hello 花了五六分钟将插件修改了一下,半支持golang了。golang语法和C比较相似,直接用C的文件修改的,主要修改了一下关键字什么的。现在对golang还不熟悉,没有随便修改。以后发现不正确慢慢修改吧。 当时安装代码高亮插件时,不知道这个东西是在插入数据库的时候修改了文章内容,现在想脱离也必须开着这个插件。想想还是这样吧,插件不更新自己慢慢修改着,反正其他插件也不一定支持,也要修改,只是可能是js实现的
Read more...

erlang学习笔记--并发编程

erlang被称作纯粹的消息传递语言。在erlang中,和进程打交道只需要3个原语:spawn、 send和receive。 1.关于erlang并发编程的一个例子。 先上代码: [caption id="attachment_618" align="alignnone" width="300" caption="erlang并发编程"]erlang并发编程[/caption] 20> c(area_server1.erl). {ok,area_server1} 21> Pid3 = area_server1:start(). <0.98.0> 22> area_server1:area(Pid3,{rectangle,10,10}). 100 <0.40.0> 代码分析: 第四行,来自并发原语Pid = spawn(Fun),创建一个新进程,对Fun求值。新进程与调用者所在的进程并发运行。spawn返回一个Pid。 第八行,并发原语Pid ! Message,想进程标识符为Pid的进程发送消息。消息发送是异步的,发送者无需等待返回结果就可继续处理自己的事务。 receive ... end 接受一个发给当前进程的消息,进行匹配,如果没有匹配到,消息会留给后续过程来处理,然后进程等待下一条消息。 当输入命令Pid3 = area_server1:start(),创建一个服务端进程。进程执行loop()函数,等待接受消息。 area_server1:area(Pid3,{rectangle,10,10}).输入命令后,将创建一个新进程(客户端进程),到代码第九行,给Pid3发送一条消息,{该客户进程id,{rectangle,10,10}}。然后等待消息返回,等待消息中,匹配模式{Pid,Response}绑定了Pid(这里是Pid3),因为receive...end里只有个匹配模式,所以只有当接受的消息为Pid时,后面的式子才会执行。 给Pid3发送消息后,17-20执行,From为客户端进程id,然后18行像客户端进程发送消息。self()现在为服务端的id,也就是Pid3。然后继续等待消息。 客户端接受消息,11行进行匹配,发现Pid正确,执行后面语句,打印self()(客户端id)。 晚上用零碎时间又修改了一下代码,方便调试。ps:这个代码开始没看懂,借助群里大牛点通了。 [caption id="attachment_620" align="alignnone" width="300" caption="erlang编程2"]erlang编程2[/caption]
Read more...

github使用小记

这几天写了很多零碎的代码,开始想直接一分类上传到网盘保存。后来发现又想用的时候,需要下载,解压。今天集成jquery一个开源上传框架,想到将这些零碎的代码上传到github上。这样看也方便,如果有需要的还可以参考一下我写的代码(虽然很乱,其实也是水平所限)。自己写过贴代码的网站不难,只是这个轮子没必要造了。开搞。。 第一步:注册。注册完了,你会看到一个GitHub Bootcamp,在正中央。哈哈,我提前先从网上找了教程瞅了几眼,虽然一直喜欢 碰到一个新东西,先蒙头研究一番,但是感觉在这里很谨慎。大部分网站喜欢把帮助文件放到一边,这可能与github需要很多操作有关。 第二步:下载git。下载地址:http://git-scm.com/download/win,安装。 设置: 用户名和邮箱
git config --global user.name "Your Name Here"
git config --global user.email "your_email@youremail.com"

设置密码过期时间一小时:
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'# Set the cache to timeout after 1 hour (setting is in seconds) 第三步:创建一个项目。https://github.com/repositories/new 配置密钥 git push origin master 生成新密钥 ssh-keygen –t rsa –C “a.0x55aa@gmai.com” 复制.ssh\id_rsa.pub文件内容到 Account Settings--->SSH keys ,add ssh key,就搞定了
第四步:上传代码。 进入本地项目创建的文件夹(命令有linux命令一样),执行命令。
git init
git clone git@github.com:0x55aa/django-image-upload
将github上的文件clone到本地,我在创建项目的时候选择了自动生成readme文件。所以这里先update一下。
如果是直接创建,需要$ git remote add origin git@github.com:0x55aa/django-image-upload
git remote -v
查看你当前项目远程连接的是哪个仓库地址
git add .
向项目添加文件
git commit –m ”new” 
更新
git push origin master
上传文件

步骤再记录下,前面有点乱。
 git clone git@github.com:0x55aa/baidu-tieba-tools
D:\git>cd baidu-tieba-tools
D:\git\baidu-tieba-tools>git add . 
git commit -m "first"
git push -u origin master
搞定
 
git config --global credential.helper 'cache --timeout=3600'# Set the cache to timeout after 1 hour (setting is in seconds)
Read more...

利用pil,cStringIO将图片暂存上传

很简单的代码,记录一下。
    import Image
    image = Image.open('a.jpg')
    import cStringIO
    buf = cStringIO.StringIO()
    image.save(buf, image.format,quality=75)
    data = buf.getvalue()
    a = u.writeFile('/this/logo.jpg',data,True)
应用在 使用django,用户上传图片后,将图片转存到别的服务器。但是转存需要对图片进行处理,但是quality设定的保存,不知道可不可以在不是image.save()的时候。写的这个是保存时放到内存,然后直接提交到图片服务器。
Read more...

erlang学习笔记--BIF,二进制数据,比特语法

1.BIF: BIF:(built-in function)内建函数,是erlang语言的组成部分。是erlang虚拟机中的基本操作。 tuple_to_list/1将元组转换为列表,time/0返回当前时间的时,分,秒。 1> tuple_to_list({12,cat,"ddd"}). [12,cat,"ddd"] 3> time(). {12,35,57} 2.二进制数据: 一种数据类型,用来实现原始数据的高速存储。节省内存,输入输出更加高效。书写打印时,二进制数据以一个整数或者字符序列的形式出现,两端分别用尖括号括起来。其中的整数,每一个都要在0-255之间,如果二进制数据是可以打印的字符串,shell将显示字符串形式,否则会显示一串整数。 @spec 描述函数的参数和返回类型。类型标注,不是erlang代码而是注释文档的一部分,shell中不能使用这些标注。erlang中的模块声明也是注释的一部分。 erlang通过BIF来构造二进制数据或者从中提取数据,或者通过比特语法来完成这一过程。 @spec list_tbo_inary(IoList) -> binary() @spec split_binary(Bin,Pos) -> {Bin1,Bin2} @spec term_to_binary(Term) -> Bin @spec binary_to_term(Bin) -> Term list_tbo_inary将IoList中所有东西转换为一个二进制数据。split_binary在pos位置将二进制数据分割成两个部分。下面两个是互逆。 4> Bin1 = <<1,2,3>>. <<1,2,3>> 5> Bin2 = <<4,5>>. <<4,5>> 6> Bin3 = <<6>>. <<6>> 7> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]). <<1,2,3,1,2,3,4,5,4,6>> 12> split_binary(<<1,2,3,1,2,3,4,5,4,6>>,4). {<<1,2,3,1>>,<<2,3,4,5,4,6>> 14> term_to_binary({11,'333a',use}). <<131,104,3,97,11,100,0,4,51,51,51,97,100,0,3,117,115,101>> 15> binary_to_term(<<131,104,3,97,11,100,0,4,51,51,51,97,100,0,3,117,115,101>>). {11,'333a',use} 返回二进制数据字节长度 16> size(<<1,2,3,4>>). 4 3.比特语法 比特语法:一种模式匹配语法,用于二进制数据中的比特进行封包和解包工作。 比特语法是模式匹配的一种扩展。编写底层代码时,常会需要对比特级别的二进制数据进行封包解包,会体现比特语法的便捷,比特语法针对协议编程而设计(erlang的看家本领 哇塞)。 16bit色彩的封包解包 19> Red = 2. 2 20> Green = 54. 54 21> Blue = 20. 20 22> Men = <<Red:5,Green:6,Blue:5>>. <<22,212>> 23> Mem = <<Red:5,Green:5,Blue:5>>. <<21,84:7>> 24> <<R1:5,G1:6,B1:5>> = Men. <<22,212>> 25> R1. 2 27> G1. 54 28> B1. 20 可以看到是用:进行匹配,冒号前是数据,后是所占的比特数。 比特语法表达式 嗯,这里讲比特语法格式: 比特语法的形式:<<>>或者<<E1,E2,E3,E4,...,En>>。Ei有四种形式: Ei = Value | Value:Size | Value/TypeSpecifierList | Value:Size/TypeSpecifierList 二进制数据中总比特数恰好被8整除(二进制数据中每个字节都是8bit)。Value必须是一个绑定变量、文本串或者一个返回值的整数。浮点数、二进制数据的表达式。Size必须为一个整型或者整型绑定变量,不能是自由变量。整型默认Size为8,浮点型为64,二进制则为本身长度。SpecifierList决定字节序,取值为: @type End = big| little |native 书上给出一个例子来了解这三种排序和默认排序,不同机器可能不同。 37> {<<16#12345678:32/big>>,<<16#12345678:32/little>>,<<16#12345678:32/native>>,<<16#12345678:32>>}. {<<18,52,86,120>>, <<120,86,52,18>>, <<120,86,52,18>>, <<18,52,86,120>>} 4.使用总结 块表达式: begin Expr1, .... Exprn end 块得值就是快中最后一个表达式的值,用于当代码某处只允许使用单个表达式而你要用一串表达式时。 注释: 只有行注释%,没有块注释。 列表操作符++ ——:对列表进行添加和删除的中缀操作符。 比较表达式: 所有类型都定义了大小比较顺序: number<atom<reference<fun<port<pid<tuple<list<binary 作用:可以对存储了任何类型的列表进行排序,并根据比较顺序,编写高效的数据访问代码。 出了=:=,=/=外,其他都遵循下面规则: 如果一个比较参数为整数,另一个浮点数, 整数在比较前需要转换成浮点数。 如果两个比较参数都是整数或者浮点数,直接比较。。。 ==只适用于浮点数和整数的比较。最好都用=:=。   下划线变量: 如果一个变量在一个字句中只被使用一次,编译器会提出警告。但以下划线开始,那么编译器不会产生警告信息。 命名不准备使用的变量,增加可读性。方便调试。
Read more...

Previous Page 1 2 3 4 5 6 7 8 9 10 Next Page 最后一页