兄弟连区块链培训教程之反射简介
兄弟连区块链培训教程并发技术2:多协程

很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连Go语言+区块链培训老师给大家介绍一下关于Go语言中并发技术2:多协程,下面我们一起来看一下吧。
创建Goroutineimport ("fmt""time")func newTask() {for {fmt.Println("劳资是子协程")time.Sleep(time.Second)}}func main() {//开一条协程,与主协程并发地执行newTask()go newTask()//主协程赖着不死,主协程如果死了,子协程也得陪着死for {fmt.Println("this is a main goroutine")time.Sleep(time.Second)}}出让协程资源通过runtime.Gosched()出让协程资源,让其他协程优先执行package mainimport ("fmt""runtime")func main() {go func() {for i := 0; i < 5; i++ {fmt.Println("go")}}()for i := 0; i < 2; i++ {//让出时间片,先让别的协程执行,它执行完,再回来执行此协程//(詹姆斯协程:先排档期,你们先上)runtime.Gosched()fmt.Println("hello")}}协程自--杀package mainimport ("fmt""runtime""time")func test() {//遗嘱:临终前说的话defer fmt.Println("这是test的遗嘱")//自杀,触发提前执行遗嘱,暴毙,后边的好日子不过了,调用它的协程也暴毙runtime.Goexit()//自杀了,后边的好日子不过了fmt.Println("生活承诺的很多美好事情...")//到这是test的正常退出}func wildMan() {for i:=0;i<6;i++{fmt.Println("我是野人,我不喜欢约束,我讨厌制约的我的主协程")time.Sleep(time.Second)}}func main() {//一个会暴毙的协程go func() {fmt.Println("aaaaaaaaaaaaaa")//test中有协程自杀程序runtime.Goexit()test()fmt.Println("bbbbbbbbbbbbbbb")}()//一个讨厌主协程约束的野人协程,主协程正常结束会把她带走//如果主协程暴毙,则野人协程失去约束go wildMan()for i:=0;i<3;i++ {time.Sleep(time.Second)}//主协程的暴毙,会令所有子协程失去牵制——野人永远失去控制//主协程暴毙的情况下,如果所有协程都结束了,程序崩溃:fatal error: no goroutines (main called runtime.Goexit) - deadlock!runtime.Goexit()fmt.Println("主协程正常返回,会带走所有子协程")}查看可用内核数package mainimport ("fmt""runtime")/*可用内核越多,并发质量越高*/func main() {//把可用的最大逻辑CPU核心数设为1,返回先前的设置previousMaxProcs := runtime.GOMAXPROCS(1)//获得逻辑CPU核心数cpu_num := runtime.NumCPU()fmt.Println("cpu_num = ", cpu_num)//8fmt.Println("previousMaxProcs=",previousMaxProcs)//8for {//主协程打0,子协程打1go fmt.Print(1)fmt.Print(0)}}协程间公平竞争资源package mainimport ("fmt""time")func PrinterVII(str string) {for _, data := range str {fmt.Printf("%c", data)time.Sleep(time.Second)}fmt.Printf("\n")}func person1VII() {PrinterVII("今生注定我爱你")}func person2VII() {PrinterVII("FUCKOFF")}func main() {go person1VII()go person2VII()for {time.Sleep(time.Second) }}。
兄弟连区块链培训教程并发技术1:CSP并发理论

很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连Go语言+区块链培训老师给大家介绍一下关于Go语言中并发技术1:CSP并发理论,下面我们一起来看一下吧。
异步async并行:多个任务并发执行同步sync串行:多个任务依次执行阻塞block某个并发任务由于拿不到资源没法干活,从而无所事事地干等异步回调asynccallbackA线程唤起B线程,令其干活同时给B一个回调函数命令B在干完活以后,执行这个回调函数这个回调函数会与A线程发生交互A不必阻塞等待B执行的结果,AB两个线程可以并发执行利弊效率高回调地狱CallbackHell,逻辑线不清晰共享内存多个并发线程通过共享内存的方式交互数据线程安全问题:AB间共享的数据地址可能被C并发修改同步锁/资源锁为了解决共享内存所导致的线程安全问题,共享的内存地址在特定时间段被特定线程锁定加锁期间,其它线程无法访问,带来低效率问题死锁A锁住B的资源B锁住A要的资源AB同时阻塞案例:小两口的冷战女:锁住女人的尊严,得到男人的尊严后才释放男:锁住男人的尊严,得到女人的尊严后才释放线程池背景:线程的开销大内存:保存上下文数据CPU:线程调度为了避免无度创建线程(内存溢出OutOfMemory),在一个池中创建一堆线程,循环利用这些线程,用完了以后重置并丢回池中.利弊利:避免了无度创建线程,降低了OOM的风险弊:用不用都占去了一大块内存开销1.线程并发的弊端2.开线程占内存啥也不干就拿走1M栈空间1024条线程就占用1G内存线程切换占CPU内存共享不安全加了锁效率又低下回调地狱导致开发难度高堆栈栈变量和对象的名称引用堆地址堆杂乱无章地堆放各种数据没有栈对其进行引用时,就由nil进行引用被nil引用的堆地中的内容随时可能被垃圾回收器回收垃圾回收一块堆内存如果没有被栈引用,就会被0号栈(空nil)所引用一切被nil引用的对内存,会随时被垃圾回收器(GarbageCollector=GC)回收CSP模型CommunicatingSequentialProcess可通信的序列化进程并发的进程间通过管道进行通信共享内存VS管道内存共享:通过内存共享通信管道:通过通信共享内存管道最早由CSP模型提出以点对点管道代替内存共享实现并发进程间的数据交互相比内存共享数据交互的相率要高很多协程coroutinecoorperte协作IO时让出CPUroutine事务微线程/纤程。
兄弟连区块链技术培训区块链共识算法(3)PoS权益证明算法

兄弟连区块链技术培训区块链共识算法(3)PoS权益证明算法# PoS权益证明算法原理及其在点点币、黑币中的实现PoS,即Proof of Stake,译为权益证明。
无论PoW或PoS,均可以理解为“谁有资格写区块链”的问题。
PoW通过算力证明自己有资格写区块链,而PoS则是通过拥有的币龄来证明自己有资格写区块链。
### PoW的优势和弊端PoW,优势为可靠,使用广泛,是经历了充分的实践检验的公有链共识算法。
但其缺点也较为明显:* 1、消耗了太多额外算力,即大量能源。
* 2、资本大量投资矿机,导致算力中心化,有51%攻击的安全隐患。
### PoS的提出和点点币第一个基于PoS的虚拟币是点点币。
鉴于PoW的缺陷,2012年Sunny King提出了PoS,并基于PoW和PoS的混合机制发布了点点币PPCoin。
前期采用PoW挖矿开采和分配货币,以保证公平。
后期采用PoS机制,保障网络安全,即拥有51%货币难度更大,从而防止51%攻击。
PoS核心概念为币龄,即持有货币的时间。
例如有10个币、持有90天,即拥有900币天的币龄。
另外使用币,即意味着币龄的销毁。
在PoS中有一种特殊的交易称为利息币,即持有人可以消耗币龄获得利息,同时获得为网络产生区块、以及PoS造币的优先权。
### 点点币的PoS实现原理点点币的PoS证明计算公式为:proofhash < 币龄x目标值展开如下:hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget x bnCoinDayWeight* 其中proofhash,对应一组数据的哈希值,即hash(nStakeModifier + txPrev.bloc k.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)。
兄弟连区块链技术培训Fabric 1.0源代码分析(47)ECDSA(椭圆曲线数字签名算法)

兄弟连区块链技术培训Fabric 1.0源代码分析(47)ECDSA (椭圆曲线数字签名算法)# Fabric 1.0源代码笔记之 ECDSA(椭圆曲线数字签名算法)## 1、椭圆曲线算法概述### 1.1、无穷远点、无穷远直线、射影平面* 平行线相交于无穷远点;* 直线上有且只有一个无穷远点;* 一组相互平行的直线有公共的无穷远点;* 平面上任何相交的两直线,有不同的无穷远点;* 全部无穷远点沟通一条无穷远直线;* 平面上全部无穷远点和全部普通点构成射影平面。
### 1.2、射影平面点定义对于普通平面上点(x, y),令x=X/Z,y=Y/Z,Z≠0,则投影为射影平面上的点为(X : Y : Z)。
如点(1,2)在射影平面的坐标为:(Z : 2Z : Z) Z≠0,即(1 : 2 : 1)或(2 : 4 : 2)均为(1, 2)在射影平面上的点。
Z=0时,(X : Y : 0)即为无穷远点,Z=0即为无穷远直线。
### 1.3、椭圆曲线方程椭圆曲线的定义:一条椭圆曲线是在射影平面上满足方程Y²Z+a1XYZ+a3YZ²=X³+a2X²Z+a4XZ²+a6Z³的所有点的集合,且曲线上的每个点都是非奇异(或光滑)的。
该方程为维尔斯特拉斯方程,是一个齐次方程。
所谓“非奇异”或“光滑”的,即满足方程的任意一点都存在切线。
椭圆曲线存在无穷远点(0, Y, 0),可以在平面坐标系中用椭圆曲线、加一个无穷远点来表示。
令x=X/Z,y=Y/Z,代入椭圆曲线方程,即椭圆曲线普通方程:y²+a1xy+a3y = x³+a2x²+a4x+a6。
### 1.4、椭圆曲线上的加法任意取椭圆曲线上两点P、Q (若P、Q两点重合,则做P点的切线)做直线交于椭圆曲线的另一点R’,过R’做y轴的平行线交于R。
我们规定P+Q=R。
根据这个法则,可以知道椭圆曲线无穷远点O∞与椭圆曲线上一点P的连线交于P’,过P’作y轴的平行线交于P,所以有无穷远点O∞+ P = P 。
兄弟连区块链技术培训分享Go语言之reflection

兄弟连区块链技术培训分享Go语言之reflectionGo语言经过十余年的发展,已成为最流行的新兴语言。
目前,Go语言已成为云计算领域的首选语言,且随着近几年区块链的流行,作为底层开发语言的Go再次火爆成为区块链领域第一编程语言,IBM的Fabic等重量级的区块链项目都是基于Go语言开发的。
殊不知,Go语言可开发的应用项目还有很多。
除云计算、区块链等开源项目外,还包含Devops、人工智能、游戏、存储引擎、Web、系统/命令行工具、中间件、测试/持续交付、文件系统等各方面的开源项目。
reflection 反射反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地反射使用TypeOf和ValueOf函数从接口中获取目标对象信息反射会将匿名字段作为独立字段(匿名字段本质)想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface通过反射可以"动态"调用方法举例1、通过反射来获取属性信息,方法信息//反射练习//获取字段的类型信息,方法信息,属性信息package mainimport ("fmt""reflect")type User struct {Id intName stringAge int}func (user User) Hello(){fmt.Println("hello world")}func main() {user := User{Id:2, Name:"xiaoqiang",Age:30}info(user)}//定义一个方法//此方法接收的是一个空接口//这样的话,其实是任何类型都可以接收了func info(o interface{}) {//获取o的类型t := reflect.TypeOf(o)fmt.Println("Type:\t", ())//取出类型后,需要对类型进行校验,//查看是否是规定的类型if k :=t.Kind(); k != reflect.Struct {//如果不是规定的Struct类型的话,就需要进行//异常处理fmt.Println("输入参数的类型不匹配!")return}//获取o的属性v := reflect.ValueOf(o)fmt.Println("Fields:\n")//开始遍历,输出字段for i := 0; i < t.NumField(); i++ {//获取属性下标f := t.Field(i)val := v.Field(i).Interface()//输出属性的名称,类型,对应的值fmt.Printf("%6s:%v = %v\n", , f.Type, val) }//开始获取方法的基本信息for i:=0; i<t.NumMethod(); i++ {m := t.Method(i)fmt.Printf("%6s:%v\n", , m.Type) }}2、反射是如何获取匿名字段呢?//反射是如何处理匿名字段的?package mainimport ("reflect""fmt")type Stu struct {Id intName stringAge int}type Man struct {//这里你要注意一下,你创建的属性,是有顺序的,是有下标的//如Stu 下标就是0,title下标就是1// Stu 就是匿名属性Stutitle string}func main() {//注意,对匿名字段进行初始化时的方式,其实本质上跟其他属性是一样的m := Man{Stu:Stu{Id:2,Name:"Jack",Age:19}, title:"Manager"}t := reflect.TypeOf(m)//取匿名字段的方式//FieldByIndex 方法,传入的是一个切片slice类型//第1个0,表示,匿名字段在Man中的下标位置//第2个0,表示,你要取匿名字段中哪个属性的下标fmt.Printf("%#v\n", t.FieldByIndex([]int{0,0})) //取的是idfmt.Printf("%#v\n", t.FieldByIndex([]int{0,1})) //取的是Namefmt.Printf("%#v\n", t.FieldByIndex([]int{0,2})) //取的是Age}3、通过反射对基本类型进行修改//如果通过反射,对基本类型进行修改package mainimport ("reflect""fmt")func main() {//下面测试,对基本类型的修改操作x := 456//传递的参数是地址v := reflect.ValueOf(&x)//Elem方法,是取出元素值来,然后通过setint方法,进行重新设置v.Elem().SetInt(789)fmt.Println(x)}4、通过反射对复杂类型进行修改//如果通过反射,对复杂类型进行修改package mainimport ("reflect""fmt")type Teac struct {Id intName stringAge int}func main() {teac := Teac{Id:5,Name:"Ant-man",Age:23}fmt.Println("teac:\t", teac)//传递的是地址哦Set(&teac)fmt.Println("teac:\t", teac)}func Set(o interface{}) {v := reflect.ValueOf(o)if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {fmt.Printf("xxx")return}else{v = v.Elem()}// 通过FieldByName 这个方法,直接输入名称,来获取f := v.FieldByName("Name")//校验,是否取到Name属性的值if !f.IsValid() {fmt.Printf("BAD")return}//然后,再校验,类型是否匹配if f.Kind() == reflect.String {f.SetString("Iron Man")}}5、通过反射对方法进行动态调用//通过反射,进行方法的调用,相当于动态调用了package mainimport ("fmt""reflect")type Teacher struct {Id intName stringAge int}//通过receiver将Show方法,跟Teacher类型,进行绑定func (teacher Teacher)Show(name string) {fmt.Println("hello, ", name, ", my name is ", )}//注意======目前没有发现====如何通过====反射===来获取=====私有方法func (teacher Teacher)info(){fmt.Println("=====")}func main() {teacher := Teacher{Id:34, Name:"Thor",Age:34}teacher.Show("Hawkeye")//下面通过反射,调用show方法v := reflect.ValueOf(teacher)//获取show方法m := v.MethodByName("Show")//校验一下,是否获取到show方法呢if !m.IsValid() {fmt.Printf("=======没有获取到制定的方法====")return}//参数必须是切片类型//reflect.Value{} 这里面,可以设定多个参数类型//目前,我们这里只有一个string类型的参数//args := []reflect.Value{reflect.ValueOf("Hulk")}m.Call(args)}。
兄弟连区块链教程Go语言基础连接MySQL数据库操作

兄弟连区块链教程Go语言基础连接MySQL数据库操作2018年时已过半,在今年的区块链热潮中,国内各家科技巨头均已粉墨登场,开始在这个新兴领域里抢占高地。
但在具体布局细节上,几大巨头又各有不同,从中亦可窥见它们各自对区块链的重视程度和期许方向。
兄弟连Go语言全栈与区块链技术培训课程是由清华、微软和谷歌名师历时半年时间研发出的独一无二的体系化课程。
课程涵盖9大学习阶段,及多个企业级项目实战和来自世界顶尖区块链比赛作品,并由以微软区块链最具价值专家尹成为代表的清华系区块链团队亲临授课,综合提升学员的职场竞争力。
(1)导入数据库驱动import (_"/doc/33994403.html,/Go-SQL-Driver/MySQL")这里使用_ 的意思是引入后面的包名而不直接使用这个包中定义的函数,变量等资源。
若出现无法导入的情况,我们可以使用以下方式解决(以window系统为例)windows+R 打开cmd,输入go get /doc/33994403.html,/vmihailenco/redis , 回车之后会自动下载项目到GOPATH中的src目录下,然后刷新IDE。
(2)数据库连接使用sql.Open 用来打开一个注册过的数据库驱动,这里有几种连接方式,如下所示,一般我们选用第二种方式user@unix(/path/to/socket)/dbname?charset=utf8user:password@tcp(localhost:3306)/dbname?charset=utf8user:password@/dbnameuser:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname(3)增删改查操作package mainimport ("database/sql""fmt"_"/doc/33994403.html,/Go-SQL-Driver/MySQL")var(DBHostsIp = "localhost:3306"DBUserName = "root"DBPassWord = "123456"DBName = "localmysql")func main(){//连接至数据库db,err := sql.Open("mysql", DBUserName+":"+DBPassWord+"@tcp("+DBHostsIp+")/"+DBN ame)CheckErr(err)insert(db)//关闭数据库连接db.Close()}//插入demofunc insert(db *sql.DB) {//准备插入操作stmt,err := db.Prepare("INSERT user (user_name,user_age,user_sex) values (?,?,?)")CheckErr(err)//执行插入操作res,err := stmt.Exec("limao",26,2)CheckErr(err)//返回最近的自增主键idid,err := /doc/33994403.html,stInsertId() fmt.Println("LastInsertId: ",id)}//查询demofunc query(db *sql.DB) {//rows:返回查询操作的结果集rows,err := db.Query("SELECT * FROM user")CheckErr(err)//第一步:接收在数据库表查询到的字段名,返回的是一个string 数组切片columns, _ := rows.Columns() // columns: [user_id user_name user_age user_sex]//根据string数组切片的长度构造scanArgs、values两个数组,scanArgs的每个值指向values相应值的地址scanArgs := make([]interface{}, len(columns))values := make([]interface{}, len(columns))for i := range values {scanArgs[i] = &values[i]}for rows.Next() {//将查询到的字段名的地址复制到scanArgs数组中err = rows.Scan(scanArgs...)CheckErr(err)//将行数据保存到record字典record := make(map[string]string)for i, col := range values {if col != nil {//字段名= 字段信息record[columns[i]] = string(col.([]byte))}}fmt.Println(record)}}//更新demofunc update(db *sql.DB) {//准备更新操作stmt1,err := db.Prepare("UPDATE user SET user_age=?,user_sex=? WHERE user_id=?") CheckErr(err) //执行更新操作res1, err := stmt1.Exec(21, 2, 1)CheckErr(err)//查询更新多少条信息num, err := res1.RowsAffected()CheckErr(err)fmt.Println(num)}//删除demofunc remove(db *sql.DB) {//准备删除操作stmt, err := db.Prepare(`DELETE FROM user WHERE user_id=?`)CheckErr(err)//执行删除操作res, err := stmt.Exec(1)CheckErr(err)//查询删除多少条信息num, err := res.RowsAffected()CheckErr(err)fmt.Println(num)}//检查错误信息func CheckErr(err error) {if err != nil {panic(err)}}总结:db.Prepare()函数用来返回准备要执行的sql操作,然后返回准备完毕的执行状态。
兄弟连区块链培训教程IPFS+区块链
兄弟连区块链培训教程IPFS+区块链很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连教育给大家介绍一下Go语言+区块链培训教程之IPFS+区块链,下面我们一起来看一下吧。
1. js-ipfs-api1. 如何使用js-ipfs-api2. 具体实现1. 安装create-react-app:sudo npm install -g create-react-app2. 创建React项目:create-react-app ipfs-http-demo3. 运行:cd ipfs-http-demo && npm start4. 安装 ipfs-api:npm install --save ipfs-api5. 完成前端逻辑6. 导入ipfs1. const ipfsApi = require("ipfs-api"); //导入IPFS2. const ipfs = ipfsApi({host:'localhost', port:'5001', protocol:'http'}); // 配置网络7. 上传字符串到IPFS中的Promise函数8. 测试9. 跨域资源共享的CORS配置1. ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT","GET","POST","OPTIONS"]'2. ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'3. ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'4. ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]'5. ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'6. 用正确的端口运行daemon1. ipfs config Addresses.API2. ipfs config Addresses.API /ip4/127.0.0.1/tcp/50013. ipfs daemon7. 测试8. 从IPFS读取数据3. IPFS图片上传与下载1. 创建React项目:create-react-app ipfs-http-pic2. cd ipfs-http-pic && npm start3. 安装ipfs-api:npm install --save ipfs-api4. App.js导入IPFS5. 实现上传图片到IPFS的Promise函数6 上传图片到IPFS4. IPFS与Ethereum1. truffle unbox react2. 安装ipfs-api3. 修改前端逻辑4. 修改合约5. truffle develop6. ipfs daemon7. npm start。
兄弟连区块链入门教程以太坊源码分析p2p-rlpx节点之间的加密链路
兄弟连区块链入门教程以太坊源码分析p2p-rlpx节点之间的加密链路一兄弟连区块链入门教程以太坊源码分析p2p-rlpx节点之间的加密链路,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
RLPx Encryption(RLPx加密)之前介绍的discover节点发现协议,因为承载的数据不是很重要,基本是明文传输的。
每一个节点会开启两个同样的端口,一个是UDP端口,用来节点发现,一个是TCP端口,用来承载业务数据。
UDP的端口和TCP的端口的端口号是同样的。
这样只要通过UDP发现了端口,就等于可以用TCP来连接到对应的端口。
RLPx协议就定义了TCP链接的加密过程。
RLPx使用了(Perfect Forward Secrecy), 简单来说。
链接的两方生成生成随机的私钥,通过随机的私钥得到公钥。
然后双方交换各自的公钥,这样双方都可以通过自己随机的私钥和对方的公钥来生成一个同样的共享密钥(shared-secret)。
后续的通讯使用这个共享密钥作为对称加密算法的密钥。
这样来说。
如果有一天一方的私钥被泄露,也只会影响泄露之后的消息的安全性,对于之前的通讯是安全的(因为通讯的密钥是随机生成的,用完后就消失了)。
## 前向安全性(引用自维基百科)前向安全或前向保密(英语:Forward Secrecy,缩写:FS),有时也被称为完美前向安全[1](英语:Perfect Forward Secrecy,缩写:PFS),是密码学中通讯协议的安全属性,指的是长期使用的主密钥泄漏不会导致过去的会话密钥泄漏。
[2]前向安全能够保护过去进行的通讯不受密码或密钥在未来暴露的威胁。
[3]如果系统具有前向安全性,就可以保证万一密码或密钥在某个时刻不慎泄露,过去已经进行的通讯依然是安全,不会受到任何影响,即使系统遭到主动攻击也是如此。
兄弟连区块链培训分享Go语言范围(Range)
兄弟连区块链培训分享Go语言范围(Range)兄弟连教育建议,用户在考虑培训周期时要切实结合自身目前所掌握的区块链知识的多少、培训的目的是简单的认知提升还是借此高薪就业等等。
兄弟连Go全栈与区块链培训课程设置为5个半月共计22周的学习时长,由浅入深进行讲解,助力于小白用户向区块链工程师的转型。
课程体系设计架构包括了区块链的基础语言Go语言、区块链后端技术体系、区块链公链、区块链分布式应用开发等内容讲解,以及到最后的面试指导和项目实战。
课程由清华微软谷歌名师团队精心打造,历时半年时间共同研发而出。
Go 语言中range 关键字用于for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。
在数组和切片中它返回元素的索引和索引对应的值,在集合中返回key-value 对的key 值。
实例package mainimport "fmt"func main() {//这是我们使用range去求一个slice的和。
使用数组跟这个很类似nums := []int{2, 3, 4}sum := 0for _, num := range nums {sum += num}fmt.Println("sum:", sum)//在数组上使用range将传入index和值两个变量。
上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。
有时侯我们确实需要知道它的索引。
for i, num := range nums {if num == 3 {fmt.Println("index:", i)}}//range也可以用在map的键值对上。
kvs := map[string]string{"a": "apple", "b": "banana"}for k, v := range kvs {fmt.Printf("%s -> %s\n", k, v)}//range也可以用来枚举Unicode字符串。
兄弟连区块链培训EOS源码分析(6)Token
兄弟连区块链培训EOS源码分析(6)Token# Token(通证)区块链一直就有币圈和链圈之分,币圈的人有的埋头挖矿,有的专卖矿机,有的专心炒币,还有的搬砖套利做交易。
而链圈的人则更关注区块链技术研发及应用。
之前这两个圈子间相互鄙视,谁也看不起谁,币圈的人鄙视链圈贫穷,装清高;链圈的人鄙视币圈只知道炒作投机,唯利是图。
但这一切都已成为过去,2015年末,以太坊的上线为两圈融合提供了可能,通过以太坊发行自己的Token(也就是常说的发币,后续把Token 统一翻译成通证)变得很容易,业内产生了”以币养链,以链促币“ 的发展新模式。
通过以上可以看出,Token(通证)在区块链的发展中起到了决定性的作用。
那Token(通证)到底是什么呢?对于大部分人来说它就是一种代币,如果去年眼光比较好的话,应该也都通过这种代币的发行赚到了一笔。
但这仅仅是从代币交易的角度在理解Token(通证),很显然,Token(通证)的真正价值不仅仅在此。
如果我们把某个区块链看成一个社群的话,那么Token(通证)就是这个生态下衡量价值的标准。
社群的组织有可能是因为某种兴趣,也可能是因为某种目的,大部分类似的社群都符合如下的特点:绝大多数人仅仅作为内容获取者,少数人充当优质内容提供者,极少数人充当社群管理者和投资者。
也就是说,虽然大部分人都对此社区感兴趣,加入了社区,但只有很少的人愿意贡献,社群人员之间更是一种弱关系,即大家之前的关系非常松散,不太可能为了某一件事情而牺牲自己的利益,协同去完成目标。
出现这种情况的主要原因在于,大部分人会认为在这个社区上做贡献并没有给自己带来任何利益,仅仅只是从兴趣出发,很难调动起社群用户的潜在的积极性。
现在很多虚拟社群都有积分体系,这些积分在社区内部会是一种身份的象征,但离开这个虚拟社群,就没有任何价值了,这就意味着个人在社区的贡献对于他的现实生活没有任何利益。
但如果社群的积分能够在二级市场上流通,能够把这些积分兑换成法币,那社群贡献就和真实社会的价值打通了,相信这将从根本上激励更多的社区人员做出贡献。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
兄弟连区块链培训教程之反射简介
首先Go是谷歌2009发布的第二款编程语言。
今天兄弟连Go语言+区块链培训老师给大家介绍一下关于Go语言之反射简介,很多人喜欢Go语言,其实是因为Go语言有其独特
的语言属性在支撑着其在编程语言界的发展,下面我们一起来看一下吧。
反射概述
∙通常的程序逻辑是:编码时先写好剧本,运行时按照写好的剧本演
∙何时创建一个什么实例,给哪个属性赋什么值,然后调用它的哪个方法都毫厘不差∙但能否在运行时动态地生成“剧本”呢?
∙根据具体的业务需要见机行事,动态地生成一个不知道具体类型会是什么的实例,动态地访问一个无法提前预知的属性或方法
∙答案是可以的,这便引出了今天的主角——反射
应用场景举例:导出商品列表到Excel
∙需求是:不管用户在界面上看到什么商品列表,当它捅一下导出按钮,就将该商品的所有属性和值写出为文件;
∙本例的难点是:我们无法预知用户会选择导出什么类型的商品数据、它有哪些属性,也就无法相应地去创建Excel数据表的列(读写Excel有相应的库,你也可以选择写出为文本文件、写出到数据库表中等等)
∙因为商品的种类太多,如果用正射去做,那么有多少商品类型我们就要写多少个s witch或if分支,然后在每一个分支里根据当前分支的具体商品类型去构造相应的Exc el数据列,这显然是蹩脚并且很难维护和扩展的
∙而通过反射来做就易如反掌了,管你来的是什么商品实例,立即动态解析得到其类别、所有属性名值,然后根据属性名去创建Excel的列,根据属性值去做数据的填充和写入
定义结构体
type Human struct {
Name string"姓名"
Age int"年龄"
}
func (h *Human) GetName() string {
fmt.Println("GetName called",)
return
}
func (h *Human) SetName(name string) {
fmt.Println("SetName called:", name)
= name
}
func (h *Human) Eat(food string, grams int) (power int) { fmt.Println("Eat called:", food, grams)
return 5 * grams
}
反射功能一览
func main() {
//创建对象(在实际开发中可以是任意未知类型)
h := Human{"bill", 60}
//获取任意对象的类型和值
getObjTypeValue(h)
//获得任意对象的所有属性
getObjFields(h)
//获取任意对象的所有方法
getObjMethods(&h)
//修改对象任意属性的值
modifyFieldValue(&h)
//动态调用对象的任意方法
callMethods(&h)
fmt.Println("after:h=", h)
}
获取任意对象的类型和值
func getObjTypeValue(obj interface{}) { oType := reflect.TypeOf(obj)
oKind := oType.Kind()
fmt.Println(oType, oKind)
oValue := reflect.ValueOf(obj)
fmt.Println(oValue)}
获得任意对象的所有属性
func getObjFields(obj interface{}) {
oType := reflect.TypeOf(obj)
oValue := reflect.ValueOf(obj)
fieldsCount := oType.NumField()
for i := 0; i < fieldsCount; i++ {
//从对象值中获取第i个属性的值,进而值的“正射”形式
fValue := oValue.Field(i).Interface()
structField := oType.Field(i)
fmt.Println(, structField.Type, structField.Tag, fValue)
}
}
获取任意对象的所有方法
func getObjMethods(obj interface{}) {
oType := reflect.TypeOf(obj)
fmt.Println(oType.NumMethod())
for i := 0; i < oType.NumMethod(); i++ { method := oType.Method(i)
fmt.Println(, method.Type) }
}
修改对象任意属性的值
func modifyFieldValue(objPtr interface{}) { //得到【指针的Value】
oPtrValue := reflect.ValueOf(objPtr) //得到【指针所指向的值(结构体)的Value】
oValue := oPtrValue.Elem()
fmt.Println(oValue)
//遍历所有属性的值
for i := 0; i < oValue.NumField(); i++ {
//根据序号拿到【属性的Value】
fValue := oValue.Field(i)
//拿到属性值的原生类型
fKind := fValue.Kind()
//fmt.Println(fKind)
//根据不同的原生类型设置为不同的值
switch fKind {
case reflect.String:
fValue.SetString("张全蛋")
case reflect.Int:
fValue.SetInt(99)
case reflect.Bool:
fValue.SetBool(false)
default:
fmt.Println("设置为其他值...")
}
}
}
动态调用对象的任意方法
func callMethods(objPtr interface{}) {
//要通过对象的oType拿取方法的参数列表(oType.In(i))
oType := reflect.TypeOf(objPtr)
//要通过对象的oValue拿取方法的具体实现(methodValue) oValue := reflect.ValueOf(objPtr)
//根据方法的数量进行遍历
for i := 0; i < oType.NumMethod(); i++ {
//预定义要传值的参数切片[]Value
args := make([]reflect.Value, 0)
//从对象的oType拿到当前的方法的methodType
methodType := oType.Method(i).Type
//根据参数个数进行遍历
//为每个参数乱怼一个同种类型反射值,丢入参数列表
//内层循环走完时,当前方法的参数列表就形成了
for j:=0;j<methodType.NumIn();j++{
//从方法的methodType获取当前参数artType
artType := methodType.In(j)
//再获取参数类型artType的原生类型
argKind := artType.Kind()
//根据不同的参数原生类型乱怼相同类型的值
switch argKind {
case reflect.String:
//获取字符串"一坨翔"的反射值Value,丢入参数列表 args = append(args,reflect.ValueOf("一坨翔"))
case reflect.Int:
args = append(args,reflect.ValueOf(100))
case reflect.Bool:
args = append(args,reflect.ValueOf(false))
}
}
//从对象值oValue中获取当前方法值methodValue
methodValue := oValue.Method(i)
//使用参数列表+方法值,反射调用当前方法 methodValue.Call(args)
}
}。