欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

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){}

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

使用

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

println(100+2*2);

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

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

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

這樣的寫法在 Java/Go 中都會報編譯錯誤,這是因為他們兩者都不支持運算符重載;

但 Python/C# 是支持的,相比之下我覺得 C# 的實現(xiàn)方式更符合 GScript 語法,所以參考 C# 實現(xiàn)了以下的語法規(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);

有幾個硬性條件:

operator

目前支持的運算符有:+-*/ == != < <= > >=

實現(xiàn)

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

其中重點就為兩步:

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

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

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

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

在編譯器中使用一個切片存放。

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

// GetOpFunction 獲取運算符重載函數(shù)
// 通過返回值以及運算符號(+-*/) 匹配重載函數(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
}

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

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

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

運行期: https://github.com/crossoverJie/gscript/blob/499236af549be47ff827c6d55de1fc8e5600b9b3/visitor.go#L387

總結(jié)

運算符重載其實并不是一個常用的功能;因為會改變運算符的語義,比如明明是加法卻在重載函數(shù)中寫為減法。

這會使得代碼閱讀起來困難,但在某些情況下我們又非常希望語言本身能支持運算符重載。

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

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

就不如下面這種直觀,所以有利有弊吧,多一個選項總不是壞事。

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

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

相關(guān)文章

  • Go語言切片常考的面試真題解析

    Go語言切片??嫉拿嬖囌骖}解析

    了解最新的Go語言面試題型,讓面試不再是難事,下面這篇文章主要給大家介紹了關(guān)于Go語言切片面試常考的一些問題,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Go語言實現(xiàn)23種設(shè)計模式的使用

    Go語言實現(xiàn)23種設(shè)計模式的使用

    設(shè)計模式是軟件工程中各種常見問題的經(jīng)典解決方案,,本文主要介紹了Go語言實現(xiàn)23種設(shè)計模式的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Go使用chan或context退出協(xié)程示例詳解

    Go使用chan或context退出協(xié)程示例詳解

    這篇文章主要為大家介紹了Go使用chan或context退出協(xié)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 詳解Go-JWT-RESTful身份認(rèn)證教程

    詳解Go-JWT-RESTful身份認(rèn)證教程

    這篇文章主要介紹了詳解Go-JWT-RESTful身份認(rèn)證教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Go語言運行環(huán)境安裝詳細(xì)教程

    Go語言運行環(huán)境安裝詳細(xì)教程

    這篇文章主要介紹了Go語言運行環(huán)境安裝詳細(xì)教程,本文講解了Linux、MAC OS、Windows下的安裝方法,同時講解了驗證是否安裝成功、第三方工具安裝運行環(huán)境的方法,需要的朋友可以參考下
    2014-10-10
  • Go?內(nèi)聯(lián)優(yōu)化讓程序員愛不釋手

    Go?內(nèi)聯(lián)優(yōu)化讓程序員愛不釋手

    這篇文章主要介紹了Go?內(nèi)聯(lián)優(yōu)化讓程序員愛不釋手,內(nèi)聯(lián)是在編譯過程中自動進(jìn)行的一類基本優(yōu)化之一,文章圍繞主題展開更多詳細(xì)介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • Go 語言結(jié)構(gòu)實例分析

    Go 語言結(jié)構(gòu)實例分析

    在本篇文章里小編給大家整理的是一篇關(guān)于Go 語言結(jié)構(gòu)實例分析的相關(guān)知識點,有興趣的朋友們可以學(xué)習(xí)下。
    2021-07-07
  • golang中如何使用kafka方法實例探究

    golang中如何使用kafka方法實例探究

    Kafka是一種備受歡迎的流處理平臺,具備分布式、可擴(kuò)展、高性能和可靠的特點,在處理Kafka數(shù)據(jù)時,有多種最佳實踐可用來確保高效和可靠的處理,這篇文章將介紹golang中如何使用kafka方法
    2024-01-01
  • golang兩種調(diào)用rpc的方法

    golang兩種調(diào)用rpc的方法

    這篇文章主要介紹了golang兩種調(diào)用rpc的方法,結(jié)合實例形式分析了Go語言調(diào)用rpc的原理與實現(xiàn)方法,需要的朋友可以參考下
    2016-07-07
  • 使用Go重試機(jī)制代碼更可靠

    使用Go重試機(jī)制代碼更可靠

    這篇文章主要為大家介紹了使用Go重試機(jī)制的使用,使你的代碼更加可靠,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評論