成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

手寫(xiě)編程語(yǔ)言-實(shí)現(xiàn)運(yùn)算符重載

人工智能 機(jī)器學(xué)習(xí)
運(yùn)算符重載其實(shí)并不是一個(gè)常用的功能;因?yàn)闀?huì)改變運(yùn)算符的語(yǔ)義,比如明明是加法卻在重載函數(shù)中寫(xiě)為減法。這會(huì)使得代碼閱讀起來(lái)困難,但在某些情況下我們又非常希望語(yǔ)言本身能支持運(yùn)算符重載。

前言

先帶來(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è)硬性條件:

  • 函數(shù)名必須是operator
  • 名稱后跟上運(yùn)算符即可。

目前支持的運(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)總不是壞事。

責(zé)任編輯:武曉燕 來(lái)源: crossoverJie
相關(guān)推薦

2009-08-12 10:47:03

C#運(yùn)算符重載

2021-12-15 10:25:57

C++運(yùn)算符重載

2021-12-16 10:40:11

C++運(yùn)算符重載

2025-02-24 11:16:20

2009-09-04 13:18:10

C#允許運(yùn)算符重載

2009-08-12 10:27:12

C#運(yùn)算符重載運(yùn)算符重載實(shí)例

2009-08-12 10:56:47

C#運(yùn)算符重載C#運(yùn)算符重載實(shí)例

2009-08-14 10:16:57

C#運(yùn)算符重載

2011-07-15 01:34:36

C++重載運(yùn)算符

2009-08-12 12:46:11

C#運(yùn)算符重載

2020-09-30 14:04:25

C++運(yùn)算符重載

2009-08-12 10:37:13

C#運(yùn)算符重載

2009-08-11 15:51:08

C#運(yùn)算符算術(shù)運(yùn)算符

2009-08-12 11:20:51

C#運(yùn)算符重載

2024-01-26 16:37:47

C++運(yùn)算符開(kāi)發(fā)

2010-01-22 17:48:46

VB.NET運(yùn)算符重載

2009-08-12 15:20:18

C#賦值運(yùn)算符復(fù)合賦值運(yùn)算符

2009-08-12 15:02:49

C#賦值運(yùn)算符簡(jiǎn)單賦值運(yùn)算符

2021-04-14 10:00:44

Python運(yùn)算符重載

2025-01-09 11:17:19

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: aaaa网站| 四虎影视免费观看 | 精产嫩模国品一二三区 | 婷婷久久精品一区二区 | 蜜桃特黄a∨片免费观看 | 欧美精品一区二区三区在线播放 | 日韩欧美高清 | 国产欧美日韩一区 | 亚洲高清在线 | 国产高清精品在线 | 亚洲视频一区二区三区 | 亚洲欧美一区二区三区视频 | 亚洲精品免费视频 | 国产福利在线 | 激情五月婷婷综合 | 日韩欧美亚洲 | 古装三级在线播放 | 国产精品久久视频 | 日本不卡一区 | 国产色| 国产精品久久久久久久午夜片 | 久久区二区 | 免费看片国产 | 国产免费一二三区 | 欧州一区二区三区 | 国产女人与拘做受视频 | 欧美h视频| 久久久www成人免费精品 | 91社区视频 | 岛国av免费在线观看 | 欧美久久久久久久久 | 成人一区二区三区在线 | 亚洲精品一区二区三区丝袜 | 波多野结衣中文视频 | 91美女在线 | 国产成人在线视频 | 亚洲高清网 | www.日韩| 伊人伊人 | 亚洲一区日韩 | 国产在线观看一区二区 |