golang笔记-Methods: a taste of OOP

方法:面向对象的味道 go代码:
package main
import (
    "fmt"
    "math"
)

type Rectangle struct{
    width,height float64
    rarea float64
}
type Circle struct{
    radius float64
}

func (r Rectangle) area() float64{
    return r.width * r.height
}
func (c Circle) area() float64{
    return c.radius * c.radius *math.Pi
}
func (r *Rectangle) setarea(a float64) {
    r.rarea = a
}
func (r Rectangle) setarea2(a float64) (Rectangle){
    r.rarea = a
    return r
}

func main(){
    r1 :=Rectangle{12,2,0}
    r1.setarea(r1.area())
    fmt.Println(r1.rarea)

    r2 := Rectangle{3,4,0}
    newr2 := r2.setarea2(r2.area())
    fmt.Println(r2.rarea)
    fmt.Println(newr2.rarea)
    c1 := Circle{10}
    c2 := Circle{2}
    fmt.Println("r1:",r1.area())
    fmt.Println(r2.area())
    fmt.Println(c1.area())
    fmt.Println(c2.area())

}
结果: D:\code>go run 7.go 24 0 12 r1: 24 12 314.1592653589793 12.566370614359172 代码中有两个同名方法area,他们前面括号里是ReceiverType,称作receiver。 拥有不同receiver的方法是不同的,即使他们有相同的名字。 内建类型不能定义方法,但是可以定义一个有方法的这种类型。如: type ages int setarea()修改了字段rarea的值,比较setarea()和setarea2(),会发现如果不使用指针,赋值操作是给了一个复制版的r, 并不是原来的值。 匿名字段代码:
package main
import "fmt"

type Human struct{
    name string
    age int
    phone string
}
type Employee struct{
    Human//Human类型的匿名字段
    speciality string
    phone string
}

func main(){
    Bob := Employee{Human{"bob",34,"777777-3"},"designer","33-22"}
    fmt.Println(Bob.name)
    fmt.Println(Bob.phone)
    fmt.Println(Bob.Human.phone)
    fmt.Println(Bob.Human.name)
}
运行结果: D:\code>go run 8.go bob 33-22 777777-3 bob 从程序中,当有字段冲突时,我们必须写全字段名称;当没有冲突时,两种方式都可以。
Read more...

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...

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