最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言實(shí)現(xiàn)運(yùn)算符重載的方法詳解

 更新時(shí)間:2022年09月19日 08:18:41   作者:crossoverJie  
這篇文章主要為大家詳細(xì)介紹了如何利用Go語(yǔ)言實(shí)現(xiàn)運(yùn)算符重載的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

先帶來(lái)日常的 GScript 更新:新增了可變參數(shù)的特性,語(yǔ)法如下:

int add(string s, int ...num){
	println(s);
	int sum = 0;
	for(int i=0;i<len(num);i++){
		int v = num[i];
		sum = sum+v;
	}
	return sum;
}
int x = add("abc", 1,2,3,4);
println(x);
assertEqual(x, 10);

得益于可變參數(shù),所以新增了格式化字符串的內(nèi)置函數(shù):

//formats according to a format specifier and writes to standard output.
printf(string format, any ...a){}

//formats according to a format specifier and returns the resulting string.
string sprintf(string format, any ...a){}

下面重點(diǎn)看看 GScript 所支持的運(yùn)算符重載是如何實(shí)現(xiàn)的。

使用

運(yùn)算符重載其實(shí)也是多態(tài)的一種表現(xiàn)形式,我們可以重寫(xiě)運(yùn)算符的重載函數(shù),從而改變他們的計(jì)算規(guī)則。

println(100+2*2);

以這段代碼的運(yùn)算符為例,輸出的結(jié)果自然是:104.

但如果我們是對(duì)兩個(gè)對(duì)象進(jìn)行計(jì)算呢,舉個(gè)例子:

class Person{
	int age;
	Person(int a){
		age = a;
	}
}
Person p1 = Person(10);
Person p2 = Person(20);
Person p3 = p1+p2;

這樣的寫(xiě)法在 Java/Go 中都會(huì)報(bào)編譯錯(cuò)誤,這是因?yàn)樗麄儍烧叨疾恢С诌\(yùn)算符重載;

但 Python/C# 是支持的,相比之下我覺(jué)得 C# 的實(shí)現(xiàn)方式更符合 GScript 語(yǔ)法,所以參考 C# 實(shí)現(xiàn)了以下的語(yǔ)法規(guī)則。

Person operator + (Person p1, Person p2){
	Person pp = Person(p1.age+p2.age);
	return pp;
}
Person p3 = p1+p2;
println("p3.age="+p3.age);
assertEqual(p3.age, 30);

有幾個(gè)硬性條件:

operator

目前支持的運(yùn)算符有:+-*/ == != < <= > >=

實(shí)現(xiàn)

以前在使用 Python 運(yùn)算符重載時(shí)就有想過(guò)它是如何實(shí)現(xiàn)的?但沒(méi)有深究,這次借著自己實(shí)現(xiàn)相關(guān)功能從而需要深入理解。

其中重點(diǎn)就為兩步:

  • 編譯期間:記錄所有的重載函數(shù)和運(yùn)算符的關(guān)系。
  • 運(yùn)行期:根據(jù)當(dāng)前的運(yùn)算找到聲明的函數(shù),直接運(yùn)行即可。

第一步的重點(diǎn)是掃描所有的重載函數(shù),將重載函數(shù)與運(yùn)算符存放起來(lái),需要關(guān)注的是函數(shù)的返回值與運(yùn)算符類型。

// OpOverload 重載符
type OpOverload struct {
	function  *Func
	tokenType int
}

// 運(yùn)算符重載自定義函數(shù)
opOverloads []*symbol.OpOverload

在編譯器中使用一個(gè)切片存放。

而在運(yùn)行期中當(dāng)兩個(gè)入?yún)㈩愋拖嗤瑫r(shí),則需要查找重載函數(shù)。

// GetOpFunction 獲取運(yùn)算符重載函數(shù)
// 通過(guò)返回值以及運(yùn)算符號(hào)(+-*/) 匹配重載函數(shù)
func (a *AnnotatedTree) GetOpFunction(returnType symbol.Type, tokenType int) *symbol.Func {
	for _, overload := range a.opOverloads {
		isType := overload.GetFunc().GetReturnType().IsType(returnType)
		if isType && overload.GetTokenType() == tokenType {
			return overload.GetFunc()
		}
	}
	return nil
}

查找方式就是通過(guò)編譯期存放的數(shù)據(jù)進(jìn)行匹配,拿到重載函數(shù)后自動(dòng)調(diào)用便實(shí)現(xiàn)了重載。

感興趣的朋友可以查看相關(guān)代碼:

編譯期: https://github.com/crossoverJie/gscript/blob/ae729ce7d4cf39fe115121993fcd2222716755e5/resolver/type_scope_resolver.go#L127

運(yùn)行期: https://github.com/crossoverJie/gscript/blob/499236af549be47ff827c6d55de1fc8e5600b9b3/visitor.go#L387

總結(jié)

運(yùn)算符重載其實(shí)并不是一個(gè)常用的功能;因?yàn)闀?huì)改變運(yùn)算符的語(yǔ)義,比如明明是加法卻在重載函數(shù)中寫(xiě)為減法。

這會(huì)使得代碼閱讀起來(lái)困難,但在某些情況下我們又非常希望語(yǔ)言本身能支持運(yùn)算符重載。

比如在 Go 中常用的一個(gè)第三方精度庫(kù) decimal.Decimal ,進(jìn)行運(yùn)算時(shí)只能使用 d1.Add(d2) 這樣的函數(shù),當(dāng)運(yùn)算復(fù)雜時(shí):

a5 = (a1.Add(a2).Add(a3)).Mul(a4);
a5 = (a1+a2+a3)*a4;

就不如下面這種直觀,所以有利有弊吧,多一個(gè)選項(xiàng)總不是壞事。

GScript 源碼: https://github.com/crossoverJie/gscript

到此這篇關(guān)于Go語(yǔ)言實(shí)現(xiàn)運(yùn)算符重載的方法詳解的文章就介紹到這了,更多相關(guān)Go語(yǔ)言運(yùn)算符重載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang匯編之控制流深入分析講解

    Golang匯編之控制流深入分析講解

    這篇文章主要介紹了Golang匯編之控制流,程序執(zhí)行的流程主要有順序、分支和循環(huán)幾種執(zhí)行流程,本節(jié)主要討論如何將Go語(yǔ)言的控制流比較直觀地轉(zhuǎn)譯為匯編程序,或者說(shuō)如何以匯編思維來(lái)編寫(xiě)Go語(yǔ)言代碼,感興趣的同學(xué)可以參考下文
    2023-05-05
  • Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù)

    Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù)

    HTTP協(xié)議是基于TCP/IP協(xié)議棧的,并且它也是一個(gè)面向普通文本的協(xié)議。這篇文章主要詳細(xì)介紹了Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù),感興趣的小伙伴可以借鑒一下
    2023-04-04
  • Go中regexp包常見(jiàn)的正則表達(dá)式操作

    Go中regexp包常見(jiàn)的正則表達(dá)式操作

    本文主要介紹了Go中regexp包常見(jiàn)的正則表達(dá)式操作,包括匹配、查找、替換和分割字符串等,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • GO中什么情況會(huì)使用變量逃逸

    GO中什么情況會(huì)使用變量逃逸

    本文主要介紹了GO中什么情況會(huì)使用變量逃逸,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • golang語(yǔ)言編碼規(guī)范的實(shí)現(xiàn)

    golang語(yǔ)言編碼規(guī)范的實(shí)現(xiàn)

    這篇文章主要介紹了golang語(yǔ)言編碼規(guī)范的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Golang 日期/時(shí)間包的使用詳解

    Golang 日期/時(shí)間包的使用詳解

    這篇文章主要介紹了Golang 日期/時(shí)間包的使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • golang?基于?mysql?簡(jiǎn)單實(shí)現(xiàn)分布式讀寫(xiě)鎖

    golang?基于?mysql?簡(jiǎn)單實(shí)現(xiàn)分布式讀寫(xiě)鎖

    這篇文章主要介紹了golang?基于mysql簡(jiǎn)單實(shí)現(xiàn)分布式讀寫(xiě)鎖,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 淺析Golang中字符串拼接問(wèn)題

    淺析Golang中字符串拼接問(wèn)題

    Go的字符串是一個(gè)不可改變的數(shù)據(jù)結(jié)構(gòu),這和其他語(yǔ)言如JAVA,C++等的設(shè)定很類似.總體來(lái)說(shuō),有如下五種拼接方式,下面我們將論述各種方式的性能問(wèn)題,以及如何選擇
    2023-04-04
  • go語(yǔ)法入門(mén)any類型的使用場(chǎng)景示例詳解

    go語(yǔ)法入門(mén)any類型的使用場(chǎng)景示例詳解

    這篇文章主要為大家介紹了go語(yǔ)法入門(mén)any類型的使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Go語(yǔ)言配置數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)

    Go語(yǔ)言配置數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)

    本文內(nèi)容我們將解釋連接池背后是如何工作的,并探索如何配置數(shù)據(jù)庫(kù)能改變或優(yōu)化其性能。文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評(píng)論

漳州市| 东阿县| 海淀区| 水富县| 博客| 上杭县| 库车县| 衡阳市| 稻城县| 长寿区| 宜昌市| 广汉市| 新津县| 定兴县| 大安市| 都安| 尚义县| 绥芬河市| 毕节市| 洛阳市| 敖汉旗| 大田县| 霍山县| 深泽县| 云林县| 湟中县| 福贡县| 临海市| 赤水市| 朝阳市| 晋城| 江永县| 高邑县| 平潭县| 赤城县| 高州市| 台北县| 定陶县| 乐都县| 乌兰察布市| 邵武市|