好,今天我们分享一个 gold 里边的一个技术,这个技术呢就是我使用 g s 怎么样调用 gold? 这个问题呢是我们一个会员问我了,然后呢?呃,给他这个搞了搞,然后并且呢把它做成了一个视频。那么首先看一下这个需求啊,比如说你在 gs 里边,浏览器里边啊,运行的是 gsgs, 要调用勾朗里边的一段代码, 呃,为什么要调用勾浪里边代码呢?因为勾浪写的程序它比较高效,是吧?呃,那这样呢,有一种技术啊,叫 web assembly, 呃,这样一个技术啊,那么简称这个 wasm, 那么如果现在你在做这些,呃,像物联网呀,呃等等这些技术啊,可能会听说有这样一个技术啊, 那么这个技术的思路是什么样子呢?就是我们勾写好的一个代码,他把编译成一个叫 wfm 这样一个文件,然后这样呢,我们就通过外界面里边的 gs 可以执行这个代码, 那么这个代码的执行效率呢?就像我们这个这够环境里边的效率差不多啊,性能非常的高,它是一种虚拟机这样一种技术啊, 它不光可以调用 gold, 那么可以调用,像 c 呀, c 加加呀,像 rust 呀,这个 gold 写的代码都可以啊,那么有哪些特点呢?第一个跨平台是吧?是一个平台无关的二经制格式,那么它编译之后啊,生成一个 w s m, 不管你是 呃 c 写的, c 加加 rust 还是 go long 写的,它都给你编译成一个二精制了啊,在不同的操作系统 架构上都可以运行,包括像浏览器啊,服务器啊,呃,像这个 lt 设备上面都可以。第二个性能非常高,因为这个代码呢,接近原声代码,就是,呃,你购运行的效率有多高,那么他编译成这种技术呢?这个运行效率也差不多啊。 那么第三个比较安全,那么提供了非常强大的安全和隔离机制,防止对这个主机系统的一个恶意的一个访问。 那么第四个就是兼容性啊,那么现有的外部技术 h m l c s s g s 那么五分的集成,呃, 可以与这个 g s 进行交互。那么多余元的知识啊,刚才我们说了,你用 c 呀, rust 呀, go 呀, c 加呀写的程序都可以编译成这个,这个点 w e s m 这样一个成效,那么另外有开放标准啊,这个模块化,然后呢建议加载等等。 那么下边呢,我们就来看啊,给大家这个这个试一下。那么现在我们有一个购物代码,我们在这打开我们的这个 visco 了,这边新建一个文件,这个文件就是这个叫 menet go, 这是文件啊, 认点构章有文件,这个文件比较简单啊,这个,呃,这这我们就直接输出一句话,就是 pat, 是吧? print 打印输出这句话呢,我们可以在哪呢?我们可以这这个说实话呀,这个 go mood 心里的 okay, 那么这样呢,有了这个之后,接下来我们希望在 g s 里边来调用它,那么要调用它之前,首先我们要把这个构程序编译成一个点, 点这个什么呀?点这个 wasssm 这样一个格式,那么首先呢,我们设计设置一下系统的环境啊,设置环境变量,这个超系统设置成 gs, 然后这个架构设置成这个 wasm, 一个一个来啊,首先设置这个, 接下来设置第二个,是吧?设置好了这两个环境之后呢,就可以这个 gobill 了, gobill 的我们就是编译当前这个输出,输出这个结果呢就是一个 w a s m 这样一个文件啊,那现在我们应 不行,你会看到这个地方会生成一个文件,这个文件就是闷点 wasm 这样一个二精制的这样一个文件。哎,有了这个之后,接下来我们还需要拷贝一个文件,就是呃 wsm 这样一个执行的一个 gs 文件, 修画的意思是 copy 当前环境外两个 gold 在什么地方呢?这个地方就找到它下边有一个 wasmexe 点, gs 这个点代表的是拷贝到当前我们这个陌路下边来,那么你执行了这个之后呢?他就给你拷贝把这个文件拷贝到当前这个环境下边来了。 那接下来有了这个文件之后,下边呢我们就可以新建一个 hdml 文件,新建一个有了银带子的 hl, 那么这个文件呢,也非常的简单啊,这里边就是一个简单一个勾代码,那么我们在里边啊,这个这部分不是很全,我们首先需要的是这部分代码,接下来在里边我们打一个这个可以创建一个这样一个结构啊。 那接下来我们在上边这个地方看一下这个 has 里边我们来呃,执行第一个,我们要加载一个 这个圆啊,这个圆就是我们要把这个拿过来,就是这个文件得给他要加载这个文件。接下来我们这个 script 就是刚才,呃,刚才我们这个代码 就是我们文档上这个代码就是这一部分,这部分呢首先呢我们扭一个 go, 扭一个 go, 因为要调用够了,接下来我们这个实力化一个流,然后 face face 就是当前目录下边刚才我生成的这个 min 点 wsm, 接下来我们后边这个地方就可以拿到这个结果啊,这个地方是这个 rap, 那么执行一个结果,接下来我们 go run 这个结果就是他会在控台啊,看一下我们这,这是这控台输出的这个内容呢?会被输出到哪啊?输出到我们这个浏览器的控台里面去,那么右键单击,我们这有一个叫 我们装了一个这个这个扩展啊,嗯,这里边叫 open wave 六, sorry, 你打开这个之后,那么右键单击检查,检查里边我们看到 ctrl 控台这里边就是我们在勾里边 写的那句话,购里边我们写了一个 hello, yebo seven billy, 你这样呢?我们在 gs 里边就可以直接访问购这个代码,并且获得他一个输出。这个还是应用比较多的啊,那么现在做这个物联网等等的一些这个这个技术现在用的也比较火热啊。 嗯,那么就是这样一个过程啊,那么下边这个是一个测试,好了,有关今天的分享呢,我们就讲这么多。
粉丝1103获赞7713

我们用 j n 来开发 wifi 应用程序的时候,有一个模板渲染模,模板渲染我们是这样的,这样用这个函数加的这个模板, 然后路由,然后代码,然后加的这个模板,把这个渲染进去,渲染到这个模板这个里面,我们看一下效果, ok, 启动完成,我要刷新一下,这样就渲染成功了。那我们要渲染多模板怎么办呢?如果我们要 有多个模板, ok, 比如我们在这里面加一个文件夹, go, 让我们把这个文件放进去, 那我们在这个地方再建一个文件 后台,前台 a whole time, 我们要要渲染,这样就是有不同的模板,我们怎么处理其实也很简单,在这个地方 根据教程我们就看到是这样,这样就可以夹在这个这个模板,来,我们看一下他是夹在这个 home 里面的, ok, 我再试试一下, 刷新一下,发现加载不到,是不是觉得很奇怪?为什么加载不到? 因为这个问题我也搞了好久,最后才发现这个地方需要加一个东西。 there, 为什么叫他不让用?需要重启一下, 哎,还是下载不到,他说没找到这个,没找到这个 home, 可以找到这个的话,我们再去 这个好像不需要 啊,就知道 这个这个加的的目录啊,主要看这个目录要和这个保持一致,保持一致,其实这里就是就是为这个模板 命名了,让我们再去看一下后台那个模板,这个也需要,也需要这样 后台的前台和后台 得不到,他为什么还是真的需要重新启动一下,这样就 ok 了。就这个 个视频想说的就是这个要加载多个模板的话,一定要在这个头部加上这个,然后这个名字,这个路径就是后面要引用这个模板的路径, 就是这个后面要引用的模板路径。 ok, 今天这个视频就说这个问题,下个视频再见。

下面我们看一下如何通过构员来读写文件。 读写文件的话,一般我们需要引入到 os 这个包,用它来打开文件。 os, 好, 首先我们需要读文件,那么先打开一个文件, 通过 os 包下面的一个 open 函数, open, 这里面传入文件名,可以带上文件的路径,它可以是一个绝对路径,也可以是相对于当前我们的购文件所在目录的一个相对路径。我们在跟我们购文件同目录下有一个 a 点 txt 这样一个文件。 好,打开它 open 函数呢,它可能会返回一个 error, 比方说你这个文件不存在,是吧?会返回一个文件,不存在这样一个错误,我们要判断一下有没有不发生,如果它不等于六的话, 说明打开文件失败了,我们打印一条日,打开文件失败,把这 l, c, c 呢也打出来,看一看到底是是什么 l, 好,如果失败的话,整个密函数直接退出 return, 我 们的密函数呢,是没有任何返回值的,所以这里面你写一个 return 就 可以了, return 后面不需要加任何东西。 好,如果文件打开成功的话,我们接下来叫读文件,那我们这个 file 文件使用完之后,一定要养成良好的习惯,把它关闭掉。 好,我们在 main 函数最后呢,需要把这个文件给关闭掉, close 一下。好,今天我们来读这个文件, 文件实际上是调用这个 file 的 read 函数, 而这个 read 函数呢,需要传一个参数,就是你要传一个 byte 切片进来,那我们需要事先准备好一个 byte 切片 content, 它是一个通过 make 来创建一个 byte 切片。 好,这个 byte 切片它的长度和容量都是一百, 那此时呢, content 里面已经存放着一百个零,因为是 button 嘛,它的零值就是零。好,我们把 content 传给 read 函数, 这样的话,由于 content 里面有一百个可以直接读起元素,所以 read 呢,它会从文件里面最多啊,能读出一百个字节,赋给 content。 好,这个 content 的 长度跟容量都是一百相等的情情况之下,我们可以把它们合二为一,合成一个,这样写跟刚才那种写法是完全等价的。 好,那如果说这个文件里面还不够一百个字节, 那它可能只有十个字节,那最终呢,只能读出十个字节放到 content 里面,那我们怎么知道到底从文件里面读出了多少个字节呢?哎,这个 read 函数啊,实际上它会返回两个值,一个整数数字和一个 l, 那 这个数字 n 呢?就代表着说我成功的从文件里面读出了多少个字节? 好啊,这个读的过程可能会发生错误,那如果说有错误发生的话, arrow 它不等于六的话,我们需要怎么办?还是把错误打印出来看一看, 如文件发生错误,然后呢,就直接 return 整个儿例函数, 那如果说没有发生错误的话,我们就可以把这个 content 里面内容呢打印出来看一看。 content, 那 此处需要注意, 我们的 content 里面内容它是有一百个字节的,而 file 里面可能会少一百个字节,那真正属于 file 里面内容的,它只是 content 的 前 n 个字节啊,只有前 n 个字节才是从文件里读出来的。 n 后面的内容依然全部是零,我们可以都打出来对比一下, 我们把整个 content 一 百个字节全部打出来对比一下。好,如果是零到 n 的 话,那这个零呢?可以不写, ok, 那 另外记十八行,十八行这发生错误的话,那实际上二十一行、二十二行执行不到嘛?包括二十三行也执行不到,那整个命函数直接退出,但是在退出之前,我们一定要记得把文件关闭一下, 把文件关闭一下,那这样的话代码看上去比较麻烦,容易出错。就说我这个文件一旦打开成功的话,每一个 return 的 地方我都需要记得把文件给关闭掉。实际上 第二十四行是在这个命函数零推出之前执行的,而第十九行也是在我的命函数零推出之前执行的。那这个,那这种情况刚好适合于使用 df, 而我们可以用 df 是 在函数零推出之前执行一段代码, 我们把 clothes 放在 different 后面,这样的话两处的 clothes 就 可以合到一处了,代码更简洁,而且你永远不会说忘记进 clothes。 为什么这个 defer close 一定要放在十四行这儿,而不是放在第九行后面呢?是因为你先要保证文件它能够成功打开,然后调 close 才是有意义的。好,我们把程序运行一下, 那第二十二行代码只输出了它的前 n 个字节,是这个样子, 二十三行代码输出了整个 content, 我 发现摁后面的全部都是零。好,这是读文件,那我发现从文件里面读出来的还是一个字节嘛?我们想把它转成字母串也很简单,你只需要 在字节切片前面加一个 string, 进行强制的类型转换就可以了啊,强制转成 string 二十三行,我先把它注置掉,我们再运行一次, 好把这样的一个字节,对吧?转成字母之后,它就是大脸猫这样三个汉字。之前我们也说过一个汉字在 u t l 八字母节下面是长三个字节,那大脸猫三个汉字的话应该是九个字节,这里面我们数一数, 刚好是九个字节。下面看一下如何用构元写一个文件,还是需要引入 os 这个包?写文件第一步还是要打开一个文件, 文件我们通过 o s open 文件呢?解文件我们通过 open file 啊。第一个参数还是文件名,而相对于当前我们的购物代码所在的目录的一个相对路径, b 点 t x t 就是 在当前幕下创建一个 b 点 t x t。 第二个参数呢,是一些选项,比方说这个 b 点 t x t 它如果不存在的话,那么我们需要首先创建,哎,就是通过 o s 下面有一个 create, 代表如果文件不存在创建,那如果文件存在的话,你是想继续往后追加内容呢?还是说直接把 new 内容全部清空,写入全新的内容? 这里面我们选择写入全新的内容,就是 o s o funk trunk 就是 trunk 把之前的老内容全部给删掉。然后如果是新创建一个文件,那这个文件我们说它是可读可写但不可执行,那我们就通过 o s 点 o, 它是一个可读可写但是不可执行。 only 如果是你新创建了一个文件,那么这个文件它的相关权限,当前用户和其他用户对它拥有一个读写或者执行什么权限呢?哎,你可以指定一下,比方说零六六六,或者是零六四四。 好,这是打开一个文件,我们在这儿给它换行一下,好,跟 to 文件是一样的,那么这个 open file 操作也可能会失败。判断一下, 如果发生异常的话,那我们需要 return 整个命函数,我们把异常打印出来观察一下。 打开文件失败, 好,如果打开成功的话,还是记得啊,千万记得,一定要把它 close 掉,用完之后把它 close 掉。 好。然后呢,我们准备往文件里面写入一个字串, 大脸猫 file 点 write 啊,向文件里面写入一段内容, 那这个 write 函数传递的必须是一个 back 的 切片,而 content 是 一个字串,从字串转成 back 的 切片也很简单,直接进行强制的类型转换就可以了。 function 好, 这个外函数呢,跟 read 一 样,也会返回两个参数,一个是数字和一个 arrow。 那 如果说这个有异常发生的话,还是需要啊,出来看一看。 写文件失败, 好,如果没有异常发生的话, n 呢?就代表说我们成功地向文件里面写出了几个字节。 print i 成功向文件写入几个字节,就是这个 n。 ok, 然后这里我改一下大脸猫,后面我追加一个换行符。好,我们可以把代码运行一下, 成功地写出了十个字节,因为大脸猫三个汉字占九个字节,一个换行符占一个字节,总共是十个字节。那我们打开这个 b 点 txt 文件看一看, 它里面有一个大脸猫,并且呢有一个换行,因为出现一个第二行,是一个空行嘛,说明第一行后面它是有一个换行符的。 好,如果我把这个地方 trunk 改成 append, 表示追加。如果这个 b 点 text 里面已经有内容了,那么我本次写作的内容呢?会追加到老内容。后面我们再运行一次, 成功,再看一下这个 b 点 taxi, 是 吧?就多了一行。 ok, 那 我们再运行一次, 它应该会再多出一行,这样现在是三行大脸猫,如果再改回 trunk 的 话,大家看一下它们的区别。 ok, 我 再运行一次。 好,又变成一个了,他把之前的内容全部给清空了,重新写入了一个大脸猫。 接下来我们看一段实践当中真实可用的完整的读取一个文本文件的代码。这里面所谓的文本文件,指的是说文件里面它存放的就是很多字,不串, 它不像图像,它里面存放的是很多字节,那我们称之为它是一个二精致文件。 ok, 还是一样,先打开一个文件 o s 点 open, 那 我们需要引入 o s 这个包。 好,如果打开文件又已经失败的话,那我们需要直接退出整个命名函数。 打开文件是吧?把 l 信息打出来,然后退出整个列函数。好,如果打开成功的话呢,我们一定要记得把文件给关闭掉。 ok, 接下来我们要反复地去读这个 b 点 txt 这样一个文本文件,我们会创建一个 reader, 它是带缓冲的一个 reader 啊, buffio new reader, 这要引入 buffio 这个包 buff 嘛,它就是 buffer 的 缩写,带缓冲。因为我们知道读写文件本身是一个非常慢的一个操作,归根到底是因为我们 cpu 每次跟瓷盘进行交互的话,这过程会很慢,所以呢,为了减少 cpu 跟瓷盘交互的次数,我们会每一次的读写会读很多,或者写很多,把它暂时的缓存起来啊,留给下一次使用。 所以这是 buff 的 作用,主要是为了提高程序的性能。好,那我们通过一个普通的 file, 把它分装成了一个带缓冲的一个 reader, 我 们通过调用一个 reader 的 readstring 啊,因为我们今天是演示的读一个文本文件吧,调这个 readstring 函数 好,这个函数呢,需要传一个参数,就是说我这个文件本身很大,里面有很多行,我不能一次性读完。那我碰到什么符号的时候可以停一下。 好,你告诉他,碰到换行符的时候停一下,注意这里面,这个换行符我们是用的单引号,它是一个字母,而不是字不串。说白了, read 整数的入参应该是一个 but, 而不是一个 string。 ok, 他 每次遇到空格符呢,会暂停一下,那么这个语句函数返回的也是两个值,读到的内容会存放在 line 这个变量里面,那么也可能会发生错误啊, line 这个变量可以随便起了。 好,那这个函数啊,我们要调用很多次,那文件里面有多少行,我们就需要调用很多次,但问题是我们并不知道文件里面有多少行,所以你可能需要写一个 for, 无限的循环, 一直的循环着去读这个文件,缩进,这样缩进。好,那什么时候这个无限循环可以退出呢?当我们读到文件末尾的时候,这个 for 就 可以退出了,我们怎么知道读到文件末尾了呢? 那么 string read string 函数,它会返回一个 arrow, 我 们就判,我们根据这个 arrow 可以 知道是否读到文件末尾了。如果这个 arrow 不 为空,并且 啊,它不为空,并且呢,它就等于 o s 点 e o f 的 话,说明读到文件末尾了,这个时候需要引入啊,这个应该是 i o 点 e o f, 那这个 e o f 是 什么错误呢?就是 and of file 缩写。就意味着说,哎,我这个 read 语句已经遇到了文件的结尾,遇到文件结尾的话,就可以退出整个 file 循环了。 ok, 那 如果说 else 啊,如果说发生了错误,但是呢,不是 u f, 是 其他错误的话,那我们就需要把这个错误打出来,看看是一个什么错误。读文件发生错误, 那同样,如果读文件发生错误的话,那你可能整个 main 函数都要退出了。注意,我们的 return 是 直接返回 这个命函数,让命函数直接结束,而我们的 break 仅仅是结束这一个 for 循环而已。 好,如果说 else 没有任何不发生,那最好我们把我们文件里面读出来的内容,把这个 let 打出来看一看, let 也是我们所需要的内容。 print let。 好,为什么我这里面用的是 print 而不是 print l n 呢?我故意不写 l n, 为什么呢? 是因为这个 readstring 函数,它虽然是碰到换行符就会暂停一下,但是它碰到的这个换行符呢,也会一并写到 line 这个参数里面去,所以 line 里面本身末尾已经包含了一个换行符, 那我这里面就不需要再加这个 l 文了,它也会换行。 ok, 我 们把这个程序运行之前呢,先看看 b 点 txt 里面是什么东西。 b 点 txt 里面是四行大懒猫。好,我们把程序运行一下, 它只输出了三个大脸猫啊,第四行没有输出,为什么呢?我们来分析一下。那么当程序读到第四行的时候,它已经碰到了这个 e、 o、 f 已经碰到文件末尾了,然后呢他把第四行读出来的大脸猫,这三个汉字实际上已经存到了烂里面,但是我们直接 break 了,我没有把这个烂经打印, 所以说在这个地方也应该在我们 break 之前也应该把烂里面内容呢打印出来, 来运行。四啊,这个时候它输出四个大脸猫。我们在演示 linux 当中,假如说第四行是一个空行,空行,那么运行代码会发生什么呢? 它输出三个大脸猫,为什么呢?因为它第四行读的时候, 它也是碰到了文件末尾,那此时呢?第四行里面什么都没有,所以 line 里面什么都没有, line 里面什么都没有,那么你在这里面 print 输出也是什么都没有输出,它 line 是 一个长度为零的这样一个字母串。 好,如果说第四行这里面我故意的按一下空格,给它添加一个空格的话,我们再来 run 一 次。 好,它同样呢会输出一个空格,因为这个时候在我们代码的第二十三号这边, line 里面就是一个空格,它会打印一个空格出来。

大家好,我是小杨,今天我们来聊一聊勾烂一点一八中的新特性范型,使用勾烂语言的小伙伴一定都不会陌生下面这种情况, 在实现不同类型的对象比大小的时候,系统的逻辑都要写上好几遍,比如下面这样, nice 函数是有两个入餐都是印子类型,当 a 小于 b 的时候,返回为处 nes flot 六十四,是比较 入餐为 flot 类型的 ab 两个对象的大小。或者我们用 interface 来完成不同类型的比较逻辑,通过判断 ab 参数的类型, 如果是印特类型的话,就把 ab 强转成印特类型做比较,如果是附点型的话,将 ab 转成附点型进行比较。随着社区对附点的呼声越来越高,最 中在三月十五号发布的购一点十八当中,发型作为最亮眼的特性受到大家广泛的关注。 ok, 我们来看一下使用发型该怎么写。首先定一个叫 nice a 里的函数,一点一八中,在函数中定义发型的方法是在函数名称后面定义类型参数,并用方括号括起来。 比如我写的这个 k 就是类型参数,类型参数可以嵌入任意类型。这里我们声明了印子型和 flout 型这个操作 是联合的一个类型,就是说这个 k 类型他既可以他要么是印特类型或者是 flot 伏点形,这里的波浪线的意思是说他的底层类型是 inter 类型,或者是底层类型是 flot 六十四,然后就 就可以在函数的入餐当中去使用这个 k 类型参数,比如声明 ab 两参数类型都是 k, 返回就是 boss 型, 直接 return a 小于 b, ok, 大家看到没有,这个使用发型之后,代码量明显少多了,我们来测试一下代码。首先我们来比较一下硬的类型,然后我们来测试一下比较底层类型, 底层类型是印特类型的,嗯,在这里可以定一个印特,大写的印特,他其实底层类型是小写的印特类型。 ok, 然后我们再来比较一下福点类型。如果我们想实际化具体类型的函数时,使用函数使用 函数加方括号的形式,然后方括号当中写的就是说你指定的具体类型。比如我们声明了一个具体类型为福典型的 ness any 函数,名称叫 nese float, 然后使用 nese float 去比较福点类型的数据,我们来跑一下, ok, 正常编影,没有报错。好了,本期视频就到这里,感谢大家的点赞关注我们,下期再见!

姐们再来看一下勾浪里边如何模拟 op 里边的属性和方法,那么勾浪里边呢,他是没有面相对象这样一个概念了,也没有封装这样一个概念,但是呢我们可以通过结构体,也就是这个 sot, 那么和函数进行绑定,来实现这个 op 这个属性和方法。 呃,那么这个呢,这个我们这个怎么样绑定的呢?就是在函数的前边加一个叫接收者,英文叫 resever, 那么这个函数呢,就变成了一个概念,叫方块这样一个概念。如果你看这个英文的书籍啊,你会看到有 receive 这样一个概念,其实就是这个函数呢, 呃,和这个结构体绑定了一起,那么就教一个方法了,比如说下边呢,我们想定一个 percent 类,然后这里边有内幕和 a 至两个 属性,还有像伊特斯利夫和 work 这么三个方法。那这种情况下呢,我们就可以定一个结构体里边有两个属性,是吧?这个其实它叫元素 alevants, 另外呢还有就是定义三个方法,这个三个方法比较特殊,就是其实还是一个函数,只不过呢在这接收了一个 焦虑,媳妇说接收者,那么这样呢,他就是变成了一个方法,下面我们就来看一下啊,所以说这一部分他们几个是一个整体,只不过是属性和方法这个分开来写了。 呃,打开我们这个 vis 扣的啊,我们这边呢再来新建一个新的这个泰斯特,这个叫 op 里边的这个模拟 op 里边的这个什么呀? prop 是吧? 属性和这个 master 是吧?模拟 op 里边属性和方法 package m。 嗯,在这里面,首先呢,我们就去定义一个结构体啊,这个 tys 定一个结构体就叫 person, 呃,刚才我们说了,这个 price 里边有两个属性啊,需要注意,如果你这个属性是公共的,在外边也可以使用,你就把这个手字母改成大写, 这个也一样啊,这个比如说 a 制,然后英特类型,如果你写渣吧,你可能不太习惯这样这种写法,是吧? 如果是在其他的包里边不可以访问,只有当前包可以访问,你就把首字母改成小写了,那么我们还改成这个内模,这个 a 制。 接下来我们再定义几个方法, faction, 呃,需要注意的,前边要加一个接受者,就是这个 person, 是吧?作为这个接受者,然后这个就是 eat 这样一个方法,这个我们就简单打印一个 it, 大家点,那么同样道理,下边是,呃, faction, 我这定义一个方法,有有这个接收者了,我们就是叫做方法了,比如说有斯利夫这样一个方法,是吧? 我以前的打印一个这个就是一个四力铺, 我们后边这个地方呢,我们就是一个发神,呃,这里边就是 person 还是 person, 那么后边这个地方叫这个什么?呃,随便啊,你不能光吃碎是吧?你还得供 做呀,是吧? lp, 这个就是 work, work 大大点。好了,好了这些之后,接下来我们就来实现这个结果题啊,这个 person mark 等于这个 person, 呃,出发一下这个结构题内幕是吧?呃,叫 tom, 然后后边这个 a 至二十除以最后一个属性要加一个逗号啊。然后接下来就是 你这个直接打印一下啊,打印一下这个坡寸,那么接下来调养坡寸里边的这个意思,看这个方法啊,这个 pom 房直接可以通过这个 结果题来调用,那么这就证明他们两个是绑定在一起的 work, 是吧?好,我们运行一下,看这个输出的 结果啊。首先是这个,这个没有问题,这个属性,是吧?这几个方法,这个是所谓的这个以 op 面相对象的思想来设计这个,用这个,这个勾浪里边啊,这种语法特性啊,怎么样来实现?

大家好,我是小猪,接下来我们继续挑战勾浪底线元码,接下来我们来分享这一个了。 up, 在 我们的一个 go 当中呢,对于二阶式数据的一个向上取整啊,其实呢主要是用我们的一个地址对齐啊。好,那么我们来看一下这个向上取整他怎么算的啊?首先 n 表示我们的一个地址 啊,我们可以认为是一个我们要算的那个数。好, a 表示我们要对齐的位数,比如说我们以八字节对齐啊,十六字节对齐啊,是吧?表示我们要对齐的这个农好,那么它返回这个结果呢?是 n 加 a 减一且, 呃,这个取非, a 减一好,在 go 里面呢,这个且加上这个取反啊,不叫取非,叫取反, 那么呢他就是一个清空操作啊。清空,比如说我们在微商里头,我们去设计一些什么标记, 那么呢我们可以通过他们的组合呢,去把我们设计的那个设置的标记呢给它清空掉。好,这样我们来看一下他这个逻辑呢,怎么样去返回一个向上去整的一个逻辑,这其实逻辑很简单,比如说我们一个数,比如说我们是十六, 我们要按八去对齐,那么呢我们向上取整呢,其实我们十六它本身是已经对齐的,所以呢我们就不需要再去对齐了。 好,如果说我们是十八,那么我们按八去对齐,我们要向上取,向下取呢?是十六,是不是向上取呢?那么就二十四,那么我们怎么去通过它去计算呢? 我们可以来看我们的一个二进制啊,比如说好,我们这呢把二进制列出来了,比如说 n 等于十六,那么呢就是二进制等于万啊,一加四个零, a 等于八,那么呢一加三个零 啊,那么 a 减一呢,就等于七,那么呢它就是三个一。好,那么我们的一个计算方式呢?我们来看一下。首先呢, n 加 a 减一,那么呢,就是我们的十六加七,是吧?那么是不是这一块十六加七 啊?那么我们的后三位呢?就是什么三个一?好,再来按我们的这个清空操作啊,也就一个取地址符号,加上一个取反, 是吧?那么取反是什么啊?我们七十三个一,他取反之后按位取反呢?他是三个零,然后再按一个且操作,是不是?所以是不是就是将我们刚才附加的这三个一给他清空掉?最后呢,得到了我们的 这一个十六,因为我们的十六呢,他本身就和我们的这个所要求的这个位数是对齐的,我们按八位对齐,按八字也对齐,他是不是已经对齐了? 所以呢,他得到的结果是一样的,是没有发生任何变化的,因为他本身就是对齐的。好,如果说我们以十八为例,我们在十六的基础上加二,右侧第二位呢,把零改成一就行了。好, 其他的条件没有变,那 a 等于八,那 a 减一呢?是等于七,好,那么我们首先去加,去计算,我们这是八加七,是不是等于二十五,对吧?好,等于二十五呢?二、坚持运算它,其实就是每个逻辑,然后呢,我们要取地址符号, 然后呢取反我们的 a 减一,是不是这个逻辑?那么取反 a 减一是什么? a 减一的取反就是三个零,然后再取地址方一算,我们就得到了什么在我们原有的计算呢?减一,那是不是就得到了二十四? 是不是逻辑?那么还有个点,我们这个地方为什么要用 a 减一?我们直接 n 加 a 行不行 啊?这大家给带入去算一下 n 加 a 行不行?比如说啊,我们的这一个十六 是吧?我们要向上取整,首先它已经对齐了,所以呢,我们无需向上取整, 所以我们得到的结果应该就是十六是吧?我们十六和八去对齐,按八位置对齐。好,如果说我们这是 a, 那 么我们的 n 加 a 是 不是十六加八,是不是就等于二十四?是吧?我们再去 取整,我们是不是就会发现我们做了多余的动作,所以这一个取整,这个向上取整是没有必要的,因为我们要做的就是确保我们这个数呢,他会进位。所以呢,我们的十六加, 我要去加八吗?我只需要加七就行了,我再到余数的基础上去减一就行了。是不是因为我们十六本身是对齐的,所以呢,他就不应该算出一个另外的值,他就应该要算出一个十六。 好,如果说我们是十八与八去对齐,那么我们十八,我们是不是加上七就可以了?加上七我们就能够等于二十五,他是不是比我们的二十四要大?是不是这个逻辑? 那么我们是不是就可以去向上去整,他能够求得一个二十四?那很多同学可能会讲,那如果说我不是十八,我是十七呢? 我十加十七加七,我们是不是刚好等于二十四?那么我们向上取整,他是不是刚好能够取到二十四,就避免了我们刚才出现这种情况,就是说我本身是一个对齐的,然后我向上取整之后, 因为我本身已经对齐了,他再额外帮我们去额外帮我们再去向上取整的一个单位啊,这样就会导致我们的空间的浪费, 是不是?所以呢,十七加七他同样能够做到我们这个二十四对齐,那很多学校,那我十六呢?那十六是不是和我们刚才情况是一样,他是不是就会算出是十六而不是二十四? 所以呢,这里是我们的一个向上取整啊的一个逻辑,在我们的这个 go 的 啊底层呢,做这种地址计算未运算 啊,经常会用到我们这个逻辑啊,所以呢,这里给大家分享一下我们这一个向上递棋的一个逻辑。好,一箭三连加关注,支持老周。

大家好,欢迎!如果你已经是个开发者了,想找一门新语言,既要有 c plus plus 那 样的性能,又要像拍访那么好写,那 go 语言你真的得看一看了。在这次快速讲解里,咱们就来一起看看 go 的 几个核心特点,聊聊它为什么在云原生和后端开发领域这么火。 好的,咱们今天路线图很简半哈,先从 go 到底是个啥聊起,然后呢,一步步看他的基本语法、数据结构,还有一些让 go 特别与众不同的功能。最后,我们会用一个实际的小项目,把所有这些知识点都串起来。 好,那么咱们就从宏观的开始吧。 go 究竟是什么?在这么多奔程语业里面,他到底凭什么能站稳脚跟? go 的 设计哲学啊,其实可以概括成三个词,快、高效、可靠。首先,它是一门变异型语言,什么意思呢?就是你的代码直接变成了机器能懂的指令,中间没那么多弯弯绕绕,所以跑起来就一个字,快。其次,它是静态类型的, 这可是个大优点,意味着在你写代码的时候,翻译器就帮你把很多潜在的类型错误给揪出来了,而不是非得等到长续跑起来才崩给你看,这就让代码稳健多了。 好了,现在咱们来看看 go, 一个非常有意思的地方。习惯了面向对象编程的朋友肯定会问, go 的 类在哪呢?答案是,它没有。 go 根本就没用传统那种复杂的类和继承,它用了一种更清亮、更灵活的方式来做事,就是这个东西,结构体,也就是 struct, 这种设计的理念是组合优于继承,说白了就是让代码结构更清晰,也更好维护。行,了解了 go 的 设计理念,现在咱们就上手看看它的语法,就从最基础的开始。怎么声明一个变量。 你看,在 go 里面,声明变量有好几种方法,但你以后见得最多的肯定是又变。这种用一个冒号加等号想逆德的简短声明, 他为什么这么流行呢?因为他实在是太方便了,你根本不用写变量是什么类型构的变易器特别聪明,他会根据你赋给他的值自己猜出来。 这就让写代码感觉有点像动态语言那么爽,但你同时又享受着静态类型的所有好处。不过记住一点哈,这个方便的写法只能在函数内部。优 好的单个数据怎么处理我们知道了,那如果我想处理一组数据呢?比如一个列表或者像字典那样的建值对集合?别担心, go 早就给你准备好了两个特别强大的内置类型,切片 slices 和映设 maps。 哎,在咱们深入了解切片之前,必须得先聊聊数值,这一点特别重要。因为 go 对 数值的定义可能跟你以前学的语言不太一样。 在 go 里,数组的长度是它类型的一部分。这是什么意思呢?就是一个长度为三的整数数组和一个长度为四的整数数组,在 go 看来是两种完全不同的东西。而且一旦声明了,这个数组的长度就定死了,永远没法改 正。是因为数组的长度是固定的,所以在实际开发中,只要你需要一个能动态变化的集合,你几乎百分之百会用切片,也就是 slice。 你可以把切片想象成一个更灵活动态的窗口,它背后还是个数组。你看生命一个切片和生命一个数组特别像,唯一的区别就是方括号里没写数字。 切片真正的威力就在于它的动态性。你看,我们可以用内置的 app 的 函数,特别轻松的往切片里加新东西,你根本不用操心底层的内存是怎么分配的, go 会在需要的时候自动帮你把切片扩大,这一切都给你安排的明明白白。 好,看完了像列表一样的数据,咱们再看看键值对怎么处理。在勾里,我们用映射,也就是 maps 来实现这个功能,它就跟你熟悉的 python 里的字典或者 java 里的哈希表差不多。 创建的时候,你需要明确指定键是什么类型,值是什么类型。你看,这又体现了钩子强静态类型的严谨性。 好了,我们已经学会了怎么用结构体、切片和印刷来组织数据了,但光有数据还不够啊,我们还需要给这些数据加上行为,让它能动起来。这就引出了我们下一个话题,函数还有一个够特有的特别强大的概念,接收器函数。 咱们还是用个实际的例子来说明。首先我们用 struct 关键词定义一个叫 build 新类型,这个结构体就像一张蓝图,它描述了一张账单应该包含哪些信息,比如说账单的名字,买了哪些东西,还有给了多少小费。 接下来就是见证奇迹的时刻了。我们定义了一个叫 format 的 函数,但是你仔细看,在函数名 format 前面有个 biu 框号, biu 的 部分,这玩意儿叫接收器。 通过声明这个接收器,我们实际上是把这个 format 函数绑定到了 biu 结构体上,这么以来, format 就 成了 biu 这个类型的一个方法。就像其他面向对象语言里类的方法一样,现在任何 biu 类型的变量都可以直接调用这个 format 方法了,是不是很酷? 哎?刚才那个例子里,你可能注意到接收器 b 上有个星号,这个星号代表我们传递的是一个指征。 我知道指真这个东西,很多新手程序员一听就头大,但他的核心思想其实特别简单,你就把他想成是处理复印件和处理原件的区别就行了, 各有默认是一种值传递的语言。这什么意思呢?就是说,当你把一个变量,比如说一个字母串传给一个函数的时候,函数拿到的其实是这个变量的值的复印件,并不是变量本身。 那么既然函数操作的是复印件,那他在函数内部对这份复印件做的任何修改,都完全不会影响到函数外面的那个原始变量。这就好比你在复印件上随便涂鸦,原件还是干干净净的。 那问题来了,如果我就是想在函数内部修改原始变量怎么办?答案就是用纸真。 你可以把指真想象成变量在内存里的地址。我们不传递值的复印件,而是直接告诉函数 a, 你 要改的数据住在这个地址,你直接去那儿操作就行了。 我们用 and 这个符号来获取一个变量的地址,而在函数的参数列表里,我们用 star 来表示这个函数要的是一个地址,也就是一个指真。 好了,现在函数拿到了这个地址,它就能顺着地址找到原始的数据,并且直接修改它。这个通过地址访问数据的操作就叫解引用,在代码里,我们还是用星号这个符号来表示,这么一来,函数对数据的修改就真的生效了。 好了,理论讲的差不多了,现在是时候把我们学到的所有东西,结构体、接受器、函数,切片、影射还有指真都整合起来,看看他们在一个真实的小项目里是怎么协同工作的。 我们要看的是一个简单的梦令航班账单生成系,它的功能很直接,用户可以创建一个新账单,往里面加商品和价格,设置小费,最后把格式化好的账单存成一个文件。 你看这段代码就是整个应用的核心交互逻辑,它用了一个 switch 语句来响应用户的输入。注意看,当用户选择 s 保存账单的时候,程序调用了 b 点 safe, 这里的 b 就是 我们之前定义的 biu 结构体的一个实例,而 safe 正是我们给 biu 结构体定义的那个接收器函数。我们前面学到的知识点在这里就完美地结合起来了。 好了,我们对 go 的 快速探索就到这里了,我们看到了它通过简洁的语法和独特的设计,在性能和开发效率之间找到了一个绝佳的平衡点, 它就是为现代的并发编程和分布式系统而生的。那么问题来了,在你的下一个项目中,当你需要构建高性能、高可靠的后端服务时,构会是你的选择吗?感谢收看!

节省系列化和反系列化是前后段工程师都会遇到的一个问题。构原理里面进行节省系列化也是一件非常简单的事情。 如果你对节省系列化还不是很了解也没关系,待会运行代码,你会对它有一个更直观的认知。 好,我们直接上代码。所谓计算器的话,是说我要把一个对象转成一个二进置的流, 说白了就是一个 byte 切片,因为只有把它转成一个二进置之后,才可以执行 io 的 存储或者是网络的传输,因为写在字盘里面的或者网上传输的本质上都是一个二进置流,而不是一个结构体。 好,那我们要把结构体转为二阶滞留。首先来定义一个结构体, 先定义一个学生,这样一个结构体简单的有一个姓名,年龄和一个性别。 我们再来定义一个班级的结构体,让这个 jason 显得更复杂一点。 班级 class, 班级有班级的 id, 它是一个字母串。那班级里面呢?有很多学生,它是一个由学生构成的一个切片。好,在 main 函数里面呢,我们来创建一个学生 s, 他的姓名会叫张三,年龄 以及性别。好,再创建一个班级的实力班级。 他的 id 我 这样写吧。嗯,清楚一点, id 是一二班,它里面的学生是一个切片。 那切片里面呢?自然是很多个学生,我这边放三个,一二三,三个学生放下来, 加个逗号。好,现在我就要把 c 这个变量,你的实例把它转为一个二净制流。欸,主转呢,需要用到我们购员标准库里面提供的一个节省,它在 encoding 个包下面有一个子包节省,这个包 好,需要通过节省包下面有一个 muscle 函数, muscle 把这个 c 的 传进了,那么呢,这个函数它返回两个值,一个是一个 byte 切片和一个 arrow, 这行代码我们就称之为 json 虚了。化, 好,如果说发生了 arrow, arrow 不 等于 new 的 话,我们需要把错误信息拔出来看一看, s n 序略化失败,然后整个命函数返回。 好,如果说成功的话,那么 bytes 就是 一个字节切片,我们就成功地把一个结构体变成了一个字节流。好,我们把这个字节流呢,再转成字母串,打出来看一看。 转成一个字母串,强制类型转换, but, ok, 我 们可以把它打印出来看看。 好,我们把代码运行一下。 好,它打出来呢,就是这样一个字母串啊,这就,这就是所谓的阶层字母串,那如果你对这个字母串看上去不是很清晰的话,也没关系啊,我们今天会把它放到我们的 sublime 编辑器里面,进行一个格式化, 让大家看的更清楚一点。我 sublime 打开一个新窗口,把这个字母串粘贴过来,然后可以把它格式化一下。 格式化, ok, 好, 那我们看到这个 jason, 它时间就是这个样子,我们来观察一下,它整体上呢,是一个大括号,班级嘛,那么 id 放这儿,冒号后面是班级的值, id 的 值 学生,是吧?因为学生是一个切片吗?所以他这边是中括号,冒号后面是一个中括号,中括号后面呢?通过逗号是吧?这面逗号,逗号,逗号分成了三个学生,三个学生,那对于每一个学生而言呢,也是一样的,这个属性的字段名称放这里,冒号后面是他对应的值。 ok, 所以 通过这样一个字母串,你能够很清晰地看到 c class 这个结构体实体里面每一个字段是什么值,看得很清楚,对吧? 好,那我们再来一个反序的话,所以反序的话,就是我要把这样一个二进制的这样一个字节流,再把它转成一个 class, 转成一个结构体。 好,那我们声明一个变量,它是一个结构体啊,它是 class 这样的一个结构体。势例。好,反序的话呢,是通过 jason 安码手, 安码手,第一个参数呢,是需要把这个字节流就是 bad 的 切片传进来。 第二个参数是,你说我把它反序的话之后用哪一个结构体来承接?我们用 c 二来承接, 但注意,这里面一定要通过取值啊,取地址,把 c 二的指针都穿进来。为什么呢?因为你在这个 imax 函数内部, 你要给 c 二的成员变量进行赋值,要改变它,所以必须要传时针。在构源里面呢, 一个函数内部,如果你想去修改一个结构体的话,必须传时针,否则你对它所做的所有修改仅在函数内部生效。一旦这个函数返回,它对外部的这个结构体是没有产生任何作用的 啊。这个称之为 jason 反序的话, 按它时候呢,它会返回一个 arrow, 反序的话可能会失败。那如果这个失败了,我们打印一下错信息, 这里面是反序略化失败。好,如果成功的话,我们不妨把 c 二打印出来看一看,因为第三十四行声明之后, c 二它里面所有的成变量全部是零值自串, 比方说像这样组串是空,对于年龄是零,对于波变量是 false, 但是我们通过反锯之后,它的值就不是零值了,那我们可以打出来看一看。 print f, 好, 要看一个结构体内部每一个成员变量的值呢?我们可以通过百分号 v 甚至百分号加 v 换行,把 c 二打印出来看一看, 我们再运行一下。好,上面是虚化的结果,下面是反虚化的结果。反虚化之后, c 二呢,我们看到它里面 每一个乘边的值已经跟我们 json 做传递的值保持一致了, ok, 这就是反虚化。 然后我们今天讲节省的使用呢,除了构员标准库里面提供了这样一个工具之外,我还想说的是一种 在实践当中有一种更加高效的方法,就是使用字节跳动他们开发的一个节省絮叨法。絮叨库,好,我们可以给大家看一下,可以去 github 上搜索一下这个库。 好,这是我直接在 github 这搜索 sonic 啊,这个库的名称叫 sonic, 直接搜索 sonic, 你 会看到这边有一个字节跳动 but dance, 它们开发的 sonic 库, 它们是一个什么呢?它们是一个非常快的节省系列化反序化库啊,它这里用了一个 bling, 是 吧?非常快,非常快。 ok, 然后呢,你点开这个链接,点到他们这个项目主页里面去, 哎,然后在地址上这边,你把前面的 h t t p s 去掉,后面的这一部分 url 拷贝下来啊,待会有用有大用。拷贝下来。拷贝下来之后啊,我们再回到代码里面,我们在 input 这边呢, 需要把刚刚拷贝的链接粘贴在这里面,哎,这就是那个包,好,下面我们就用 sonic 取代刚才的接收 虚的话,这边把接收这个包替换成 sonic 包,反虚的话也是把接收包替换成 sonic 包好,这样的话代码就改完了。但是呢,现在还不能运行啊,这取决于说我们在购源里面,如果一旦引用第三方库的话, 那么就需要通过 go mode 来进行包的管理啊。我现在简单介绍一下,后面还会专门开课来讲, 我们首先通过 go mode 编辑命令来生成一个 go 点 mode 这样的文件,后面这个名字随便取,我取一个 g 六好 回车。好,这行命令有什么作用呢?它的作用实际上是说它就帮我们生成了一个 go 点 mode 这样的一个文件,这个文件刚才是没有的,是通过我运行这个命令之后才生成的, 我们现在不用去关心这个文件里面是什么。好,接下来你需要再执行一个命令 go get, 然后把刚刚考的那 e r 链接 刚刚拷贝的啊,这个 url 地址呢?再放到你的 go get 后面回车。好,执行完这两步之后,我们就可运行我们的 go 代码了, go run, ok, 那 这个呢,就是通过 sonic 执行的序略化和反序略化,结果跟刚才使用 go 标准库执行的结果是一模一样的。 那为什么要讲这个 sonic 呢?因为 sonic 它比 go 标准库里面的计算要快很多,我们以后可以呃,录一节课,专门讲一讲 通过构源如何做性能测试。你要对比两个方法,哪一个性能更好啊?今天关于节省的部分我们就讲到这里。

如果你写过一段时间构员,你就发现 option 模式真的是随处可见,那 option 算是一种设计模式吗?我觉得应该算,因为设计模式本质上就是有很多人约定俗成的一种编码套路嘛, 所以 option 模式应该算是构员里面一种很特殊的设计模式。那问题是,你会在编码中主动地去使用,去设计 option 模式吗?答案估计是否定的,因为很多人其实不知道 option 模式该如何实现, 所以本期视频呢,我们先来认识一下 up 式模式,然后来自己实现一下 up 式模式。如果你想快速高效的学习构源,欢迎点击视频下方的课程链接,通过我的对比总结和整理,带你看透本质,少走弯路。 先来看几个 option 模式的使用场景,比如在加 pc 里面,我们创建一个客户端 client, 那 必备参数是传入服务端的 ip 和地址。而下面这个 with default call options, 这个就是一个 option, 它在函数前面里面呢,是一个 dial option, 不 定长参数。当我们将来去掉某个 g i p 接口时,除了传常规的 context 和 request 之外,还可以再传若干个 option, 它们是 call option, 也是一个不定长参数。 再来看,在 i n o 框架里面这边呢,我们创建了一个大元模型 deep seek, 核心参数是需要指定 a, p, i k 和模型名称, 同时呢还指定了温度和 max tokens, 这一些参数全部用来约束我们的大元模型时传递 context 和若干条 message, 这个是必选参数。 同时呢,你还可以加一些不定长参数 model option。 比如此处我就特别指明了温度和 max tokens, 也就是说,如果在这个地方,我没有指定不定长参数的话,那么还是以当初去创建模型时,默认的温度一点零和 max tokens 等于一千为准。而如果这次我特别指明了,就以我指明的为准。再比如说,在 e t c d 中, 我们就写入一条 k 八六, k 和八六当然是必填参数,同时呢,也可以指定 op option, 此处我们是指定了足月 id。 通过以上几个例子,我们发现 option 模式总是作为不定常参数出现的,可以设置一个,也可以多个,甚至也可以不设置。 那它为什么要设置呢?很多时候是想修改默认配置,如果不设置就是不修改默认配置,那么接下来我们来自己实现一下 opt 模式。比如这个地方,我仿照 i know 也自己写了一个 model 结构体,包含了温度和 max tokens, 然后 model 有 一个 run 方法表示运行这个模型。此处呢,是简单地打印出了 window 和 max tokens, 然后搞了一个工具结构体,然后搞了一个 agent 智能体,它里面呢包含了模型和多个工具, 然后作为智能体,它有一个 query, 表示我要去运行这个智能体。那么在运行智能体时,我需要去调用智能体里面的 model。 调用模型的软方法。比如下面我创建一个智能体, 里面呢传了一个 model, 那 model 配置的温度是一点零, max tokens 是 一百,然后通过调用智能体的 query, 实际上变相地去调用了这个 model 的 run 方法。 好,那么此处当我在真正的运行时,我想传若干个 option, 想去修改这里面的关于模型的默认配置,那如何实现呢? 我可以在这边再创建一个结构体叫做 model option, 那 么它里面呢,也包含温度和 max token 这两个成员。我进到 query 函数里面来, 我去便利这些一个 option for instance, 便利对每一个 option 来说,我看看它里面的温度和 max tokens 有 没有值,如果有值的话,我就用这个值去替换掉原本 agent 里面的 model 里面的这些个默认值。比如说我用 option 里面的 temperature。 好, 我要替换掉 agent 里面的 model 里面的 temperature。 好, 同理, 我用 option 里面的 max tokens 替换掉智能题里面的 model 里面的 max tokens。 当然了,前提是说 option 里面这个 temperature 它得有值。那我怎么知道它有没有值呢? 因为即使你没有显示的给它负值,在勾圆里面呢,它也是零值。所以为了区分出你到底有没有人为的给它负过值,这边呢,我统一的改成时针, 因为时针如果没有显示负值的话,是六嘛,显示负过值就不是六了,哪怕这个值是零,加一个判断,如果说它不等于六的话,那么我才会去覆盖 model 里面的默认值。 这边需要从时针转为非时针,加一个信号,下面也进行一个判断,它不等于空时针的话,这边加一个信号,转为非时针。我们来测试一下。第一次呢,我直接运行这个智能题, 没有传任何的 model option, 那 么它当然应该是以默认的一点零和一百来运行。那么第二次我想传一个 option, 比如我想把温度修改成一点五, 那么我这边来构造一个 option, option 一, 它等于 model option, 我 要给温度特别赋一个值,它的值是一个指数嘛?所以这边 我要先创建一个变量,它等于一点五,然后这边来一个取值 temp, 然后把这个 option 呢放到我的不定常参数里面来。 当然我也可以是代表这种创建实力的形式。比如说我这边来一个 funk with temperature, 传一个温度作为参数进来,我给你返回一个 model option, model option temperature, 直接取这个参数的地址,这样搞,那么我这边就可以改改,改成 with temperature, 比如传一个一点五,进了 这行就可以不要了,删掉。那么既然可以 with temperature, 自然也可以 with max tokens 拷备份改造一下。 好,那改造完成之后,我们来一个 option 二,它就是 with max tokens, 本来是一百嘛,这次的话我们改成三百, 再来调一次我们的智能体,这边传一个,然后呢,再传一个,传两个 option, 好跑一下,这是第一次全部使用默认配置,这是第二次。把温度改成一点五,这是第三次把温度改成一点五, max tokens 改成三百, 这是 option 模式的核心思想,但是从形式上讲,还有很多种变体,我举个例子,比如这边我可以把这个 mod option 从结构体改成函数。好,这边我直接改成一个函数, 那这个函数本质上还是想去修改这个默认的 model 嘛,所以呢,这个函数接收一个参数就是 model, 而且它想修改 model, 所以 这边应该是 model 的 职称。那既然说 model option 是 一种函数的话,那么在这个地方就不能这样写了, 删掉,你就把 option 想象成是一个函数来使用参数传一个 model 之真,而这个 model 就是 a 点 model, 前面加一个趋值符号。那么下面我如何去构造一个 model option 呢?就是你直接去返回一个 function 嘛,返回一个函数,那这个函数想干嘛呢? 这个函数自然是想去修改这个 model 对 应的 temperature, 所以 是 m 点 temperature, 等于我这边的参数 temperature 好。 同理,下面这个 返回 option 实际上是返回一个函数,这个函数的目标,大家就想去修改这个 model 的 max tokens 等于参数 max tokens 好, 改作完毕,命令函数完全不用动, 我们再来运行一次 go run, ok, 那 么第二次跟第一次这个结果是完全一样的。 所以还是那句话,设计模式啊,思想大为形式,从形式上你可以写出各种变体, 但都是围绕着那一个核心思想来的。 option 模式的核心思想就是,我通过不定常参数的形式,我想去临时的修改某个默认配置, 当然了,如果你不想修改,直接把编辑成参数置空就可以了。来一个思考题。其实呢,还有很多地方,他们是把 option 搞成一种接口 interface, 这个该如何实现呢? 其实思路很直接,我们在构想编辑课程里面有一节课专门讲过函数跟接口的互换性, 介绍一下我录制的构源课程狗粮从入门到通天,包含了三大部分,第一部分,夯实基础,构源语法精讲,从最基础的开发环境搭建讲到并发,再到数据库网络和 java 编程, 不但讲的很精很细,而且总结了新手的常见问题,可能会踩到各种坑。第二步,项目实战构员框架大全,包含了配置文件、各种数据库外观开发框架、消息队列、爬虫、 k 八 s 依赖住控制反转等等,各种框架应有尽有。 然后通过信息发布系统、秒杀系统、 im 通讯系统来对这些框架进行综合的巩固和演练。第三步,大场冲刺底层代码时间,我们要亲手自己写一个日制框架, rpc 框架、搜索引擎框架和分布式一致性协议, 会总结日式开发中水库优化的各种技巧,探讨一些高级的兵法技能,法式的应用场景,为服务的监控系统调优分布式事务设计模式等等等等, 帮你快速境界提升。关于更详细的课程目录以及试听方式,大家可以点击视频下方的课程链接进行了解。

大家好,我是周,现在我们继续挑战勾浪底层元码。现在我们来介绍我们这一个向下对齐的一个逻辑,和我们的向上对齐呢,是相对应的啊,我们向上对齐呢,比如说我们的这一个二十一,我们按八去向上对齐呢,我们应该取到二十四 好,如果说我们向下对齐呢,我们应该取到十六好。但是呢有一个大前提啊,就我们这一个参数, a 必须是二的密次,如果说不是二的密次,那么我们这个 a 减一呢, 他就没有什么参考意义,因为我们的这一个对齐,向上对齐也好,向下对齐也好,他的本质是做一个清空操作啊,把我们这一个 a, 他的二进制啊,比如说我们的 a 等于八, 那么呢他的二进是什么?一后面带三个零,那么 a 减一呢?那就是他的低位,是吧?把他的这个低位相关的呢 清空掉,所以呢,他的本质啊,是清空这个 a 减一,二进制的这几个位。所以呢向下取整和我们的向上取整呢,不一样的点在哪里?我们向上取整呢,我们要保证他向上,所以呢,我们要来一个什么 n 加上 a 减一, 是这个逻辑,而如果说向下取整呢,我们就没有这个必要了啊。所以呢,我们可以看我们这个案例,向下取整,我们来看一下,首先比如说我们的 n 等于十六, a 等于八,那么呢我们向下取整,我们看一下,它是 n 清除掉,我们的 a 减一,清除动作呢?它是一个取反动作,是吧?是一个取反 a 减一,取反 a 减一呢?比如说我们的啊八 a 减一就是七,七就是三个一,三个一取反呢,是三个零啊,那么这么一算呢,它是不是就等于我们的 十六,它没有发生变化啊?因为它本身就是对齐的,所以我们向上去转也好,向下去转也好,它都不会发生变化啊,就向上对齐,向下对齐,它都不会发生变化,因为它本身就是对齐的。第二个呢,如果说我们的 n 等于十八, a 等于八,那么 a 减一呢,等于七,那么我们向下取整啊,那么这里我们改一下啊,我们的七啊,三个一取反呢,就三个零,然后按取地址符号二进置的按位语, 那么呢,我们后面这三位是不是又归零了,最后得到的呢?他应该是我们的十六, 是不是?所以呢,这是我们的这一个向下取整,在这呢两种算法一对比呢,我们其实就知道啊,我们为什么要去做一个啊,加上这个 a 减一 啊,前面呢,我们的这一个向上取整算法呢,我们有去对 a 减一这个点进行描述啊,有兴趣的同学呢,可以去翻看一下前面的一个视频啊。好,那么我们今天的内容呢,就分享到这里,一键三连加关注,支持老周。