[{"data":1,"prerenderedAt":1533},["ShallowReactive",2],{"content:\u002F2025\u002F09\u002Fproto-install":3,"surround:\u002F2025\u002F09\u002Fproto-install":1522},{"id":4,"title":5,"body":6,"categories":1499,"date":1501,"description":1502,"draft":1503,"extension":1504,"image":1505,"meta":1506,"navigation":55,"path":1508,"permalink":1505,"published":1505,"readingTime":1509,"recommend":1505,"references":1505,"seo":1514,"sitemap":1515,"stem":1516,"tags":1517,"type":1519,"updated":1520,"__hash__":1521},"content\u002Fposts\u002F2025\u002F09\u002Fproto-install.md","Protocol Buffers 安装与 Go 插件配置",{"type":7,"value":8,"toc":1490},"minimark",[9,13,17,192,195,245,253,300,304,313,320,574,578,581,605,608,628,631,641,644,647,653,895,898,1205,1213,1216,1483,1486],[10,11,12],"h2",{"id":12},"命令行安装",[14,15,16],"h3",{"id":16},"linux",[18,19,24],"pre",{"className":20,"code":21,"language":22,"meta":23,"style":23},"language-bash shiki shiki-themes github-light github-dark","# 更新包列表\nsudo apt update\n\n# 安装 unzip（后面解压 protoc 用）\nsudo apt install -y unzip\n\n# 下载 protoc（这里用 v27.1，你也可以换最新的）\nPROTOC_ZIP=protoc-27.1-linux-x86_64.zip\nwget https:\u002F\u002Fgithub.com\u002Fprotocolbuffers\u002Fprotobuf\u002Freleases\u002Fdownload\u002Fv27.1\u002F$PROTOC_ZIP\n\n# 解压到 \u002Fusr\u002Flocal\nsudo unzip -o $PROTOC_ZIP -d \u002Fusr\u002Flocal bin\u002Fprotoc\nsudo unzip -o $PROTOC_ZIP -d \u002Fusr\u002Flocal 'include\u002F*'\n\n# 删除压缩包\nrm -f $PROTOC_ZIP\n","bash","",[25,26,27,36,50,57,63,80,85,91,105,117,122,128,151,169,174,180],"code",{"__ignoreMap":23},[28,29,32],"span",{"class":30,"data-line":31,"line":31},"line",1,[28,33,35],{"class":34},"sJ8bj","# 更新包列表\n",[28,37,39,43,47],{"class":30,"data-line":38,"line":38},2,[28,40,42],{"class":41},"sScJk","sudo",[28,44,46],{"class":45},"sZZnC"," apt",[28,48,49],{"class":45}," update\n",[28,51,53],{"class":30,"data-line":52,"line":52},3,[28,54,56],{"emptyLinePlaceholder":55},true,"\n",[28,58,60],{"class":30,"data-line":59,"line":59},4,[28,61,62],{"class":34},"# 安装 unzip（后面解压 protoc 用）\n",[28,64,66,68,70,73,77],{"class":30,"data-line":65,"line":65},5,[28,67,42],{"class":41},[28,69,46],{"class":45},[28,71,72],{"class":45}," install",[28,74,76],{"class":75},"sj4cs"," -y",[28,78,79],{"class":45}," unzip\n",[28,81,83],{"class":30,"data-line":82,"line":82},6,[28,84,56],{"emptyLinePlaceholder":55},[28,86,88],{"class":30,"data-line":87,"line":87},7,[28,89,90],{"class":34},"# 下载 protoc（这里用 v27.1，你也可以换最新的）\n",[28,92,94,98,102],{"class":30,"data-line":93,"line":93},8,[28,95,97],{"class":96},"sVt8B","PROTOC_ZIP",[28,99,101],{"class":100},"szBVR","=",[28,103,104],{"class":45},"protoc-27.1-linux-x86_64.zip\n",[28,106,108,111,114],{"class":30,"data-line":107,"line":107},9,[28,109,110],{"class":41},"wget",[28,112,113],{"class":45}," https:\u002F\u002Fgithub.com\u002Fprotocolbuffers\u002Fprotobuf\u002Freleases\u002Fdownload\u002Fv27.1\u002F",[28,115,116],{"class":96},"$PROTOC_ZIP\n",[28,118,120],{"class":30,"data-line":119,"line":119},10,[28,121,56],{"emptyLinePlaceholder":55},[28,123,125],{"class":30,"data-line":124,"line":124},11,[28,126,127],{"class":34},"# 解压到 \u002Fusr\u002Flocal\n",[28,129,131,133,136,139,142,145,148],{"class":30,"data-line":130,"line":130},12,[28,132,42],{"class":41},[28,134,135],{"class":45}," unzip",[28,137,138],{"class":75}," -o",[28,140,141],{"class":96}," $PROTOC_ZIP ",[28,143,144],{"class":75},"-d",[28,146,147],{"class":45}," \u002Fusr\u002Flocal",[28,149,150],{"class":45}," bin\u002Fprotoc\n",[28,152,154,156,158,160,162,164,166],{"class":30,"data-line":153,"line":153},13,[28,155,42],{"class":41},[28,157,135],{"class":45},[28,159,138],{"class":75},[28,161,141],{"class":96},[28,163,144],{"class":75},[28,165,147],{"class":45},[28,167,168],{"class":45}," 'include\u002F*'\n",[28,170,172],{"class":30,"data-line":171,"line":171},14,[28,173,56],{"emptyLinePlaceholder":55},[28,175,177],{"class":30,"data-line":176,"line":176},15,[28,178,179],{"class":34},"# 删除压缩包\n",[28,181,183,186,189],{"class":30,"data-line":182,"line":182},16,[28,184,185],{"class":41},"rm",[28,187,188],{"class":75}," -f",[28,190,191],{"class":96}," $PROTOC_ZIP\n",[14,193,194],{"id":194},"mac",[18,196,198],{"className":20,"code":197,"language":22,"meta":23,"style":23},"# 下载\ncurl -SL -O https:\u002F\u002Fgithub.com\u002Fprotocolbuffers\u002Fprotobuf\u002Freleases\u002Fdownload\u002Fv33.2\u002Fprotoc-33.2-osx-aarch_64.zip\n\n# 解压\nsudo unzip -o protoc-33.2-osx-aarch_64.zip -d .\u002Fprotoc\n",[25,199,200,205,219,223,228],{"__ignoreMap":23},[28,201,202],{"class":30,"data-line":31,"line":31},[28,203,204],{"class":34},"# 下载\n",[28,206,207,210,213,216],{"class":30,"data-line":38,"line":38},[28,208,209],{"class":41},"curl",[28,211,212],{"class":75}," -SL",[28,214,215],{"class":75}," -O",[28,217,218],{"class":45}," https:\u002F\u002Fgithub.com\u002Fprotocolbuffers\u002Fprotobuf\u002Freleases\u002Fdownload\u002Fv33.2\u002Fprotoc-33.2-osx-aarch_64.zip\n",[28,220,221],{"class":30,"data-line":52,"line":52},[28,222,56],{"emptyLinePlaceholder":55},[28,224,225],{"class":30,"data-line":59,"line":59},[28,226,227],{"class":34},"# 解压\n",[28,229,230,232,234,236,239,242],{"class":30,"data-line":65,"line":65},[28,231,42],{"class":41},[28,233,135],{"class":45},[28,235,138],{"class":75},[28,237,238],{"class":45}," protoc-33.2-osx-aarch_64.zip",[28,240,241],{"class":75}," -d",[28,243,244],{"class":45}," .\u002Fprotoc\n",[246,247,248,249,252],"p",{},"记得把环境变量加入",[25,250,251],{"code":251},"~\u002F.zshrc","中",[18,254,256],{"className":20,"code":255,"language":22,"meta":23,"style":23},"# protoc\nexport PROTOC=\"\u002Fopt\u002Fprotoc\"\nexport PATH=\"$PROTOC\u002Fbin:$PATH\"\n",[25,257,258,263,276],{"__ignoreMap":23},[28,259,260],{"class":30,"data-line":31,"line":31},[28,261,262],{"class":34},"# protoc\n",[28,264,265,268,271,273],{"class":30,"data-line":38,"line":38},[28,266,267],{"class":100},"export",[28,269,270],{"class":96}," PROTOC",[28,272,101],{"class":100},[28,274,275],{"class":45},"\"\u002Fopt\u002Fprotoc\"\n",[28,277,278,280,283,285,288,291,294,297],{"class":30,"data-line":52,"line":52},[28,279,267],{"class":100},[28,281,282],{"class":96}," PATH",[28,284,101],{"class":100},[28,286,287],{"class":45},"\"",[28,289,290],{"class":96},"$PROTOC",[28,292,293],{"class":45},"\u002Fbin:",[28,295,296],{"class":96},"$PATH",[28,298,299],{"class":45},"\"\n",[10,301,303],{"id":302},"github-安装","Github 安装",[246,305,306,307],{},"前往 ",[308,309,310],"a",{"href":310,"rel":311},"https:\u002F\u002Fgithub.com\u002Fprotocolbuffers\u002Fprotobuf\u002Freleases",[312],"nofollow",[246,314,315,316,319],{},"对应的",[25,317,318],{"code":318},"protoc","目录树",[18,321,323],{"className":20,"code":322,"language":22,"meta":23,"style":23},"pzj@pzjmac protoc % tree\n.\n├── bin\n│   └── protoc\n├── include\n│   └── google\n│       └── protobuf\n│           ├── any.proto\n│           ├── api.proto\n│           ├── compiler\n│           │   └── plugin.proto\n│           ├── cpp_features.proto\n│           ├── descriptor.proto\n│           ├── duration.proto\n│           ├── empty.proto\n│           ├── field_mask.proto\n│           ├── go_features.proto\n│           ├── java_features.proto\n│           ├── source_context.proto\n│           ├── struct.proto\n│           ├── timestamp.proto\n│           ├── type.proto\n│           └── wrappers.proto\n└── readme.txt\n\n6 directories, 17 files\n",[25,324,325,339,344,352,363,370,379,389,399,408,417,429,438,447,456,465,474,484,494,504,514,524,534,545,554,559],{"__ignoreMap":23},[28,326,327,330,333,336],{"class":30,"data-line":31,"line":31},[28,328,329],{"class":41},"pzj@pzjmac",[28,331,332],{"class":45}," protoc",[28,334,335],{"class":45}," %",[28,337,338],{"class":45}," tree\n",[28,340,341],{"class":30,"data-line":38,"line":38},[28,342,343],{"class":75},".\n",[28,345,346,349],{"class":30,"data-line":52,"line":52},[28,347,348],{"class":41},"├──",[28,350,351],{"class":45}," bin\n",[28,353,354,357,360],{"class":30,"data-line":59,"line":59},[28,355,356],{"class":41},"│",[28,358,359],{"class":45},"   └──",[28,361,362],{"class":45}," protoc\n",[28,364,365,367],{"class":30,"data-line":65,"line":65},[28,366,348],{"class":41},[28,368,369],{"class":45}," include\n",[28,371,372,374,376],{"class":30,"data-line":82,"line":82},[28,373,356],{"class":41},[28,375,359],{"class":45},[28,377,378],{"class":45}," google\n",[28,380,381,383,386],{"class":30,"data-line":87,"line":87},[28,382,356],{"class":41},[28,384,385],{"class":45},"       └──",[28,387,388],{"class":45}," protobuf\n",[28,390,391,393,396],{"class":30,"data-line":93,"line":93},[28,392,356],{"class":41},[28,394,395],{"class":45},"           ├──",[28,397,398],{"class":45}," any.proto\n",[28,400,401,403,405],{"class":30,"data-line":107,"line":107},[28,402,356],{"class":41},[28,404,395],{"class":45},[28,406,407],{"class":45}," api.proto\n",[28,409,410,412,414],{"class":30,"data-line":119,"line":119},[28,411,356],{"class":41},[28,413,395],{"class":45},[28,415,416],{"class":45}," compiler\n",[28,418,419,421,424,426],{"class":30,"data-line":124,"line":124},[28,420,356],{"class":41},[28,422,423],{"class":45},"           │",[28,425,359],{"class":45},[28,427,428],{"class":45}," plugin.proto\n",[28,430,431,433,435],{"class":30,"data-line":130,"line":130},[28,432,356],{"class":41},[28,434,395],{"class":45},[28,436,437],{"class":45}," cpp_features.proto\n",[28,439,440,442,444],{"class":30,"data-line":153,"line":153},[28,441,356],{"class":41},[28,443,395],{"class":45},[28,445,446],{"class":45}," descriptor.proto\n",[28,448,449,451,453],{"class":30,"data-line":171,"line":171},[28,450,356],{"class":41},[28,452,395],{"class":45},[28,454,455],{"class":45}," duration.proto\n",[28,457,458,460,462],{"class":30,"data-line":176,"line":176},[28,459,356],{"class":41},[28,461,395],{"class":45},[28,463,464],{"class":45}," empty.proto\n",[28,466,467,469,471],{"class":30,"data-line":182,"line":182},[28,468,356],{"class":41},[28,470,395],{"class":45},[28,472,473],{"class":45}," field_mask.proto\n",[28,475,477,479,481],{"class":30,"data-line":476,"line":476},17,[28,478,356],{"class":41},[28,480,395],{"class":45},[28,482,483],{"class":45}," go_features.proto\n",[28,485,487,489,491],{"class":30,"data-line":486,"line":486},18,[28,488,356],{"class":41},[28,490,395],{"class":45},[28,492,493],{"class":45}," java_features.proto\n",[28,495,497,499,501],{"class":30,"data-line":496,"line":496},19,[28,498,356],{"class":41},[28,500,395],{"class":45},[28,502,503],{"class":45}," source_context.proto\n",[28,505,507,509,511],{"class":30,"data-line":506,"line":506},20,[28,508,356],{"class":41},[28,510,395],{"class":45},[28,512,513],{"class":45}," struct.proto\n",[28,515,517,519,521],{"class":30,"data-line":516,"line":516},21,[28,518,356],{"class":41},[28,520,395],{"class":45},[28,522,523],{"class":45}," timestamp.proto\n",[28,525,527,529,531],{"class":30,"data-line":526,"line":526},22,[28,528,356],{"class":41},[28,530,395],{"class":45},[28,532,533],{"class":45}," type.proto\n",[28,535,537,539,542],{"class":30,"data-line":536,"line":536},23,[28,538,356],{"class":41},[28,540,541],{"class":45},"           └──",[28,543,544],{"class":45}," wrappers.proto\n",[28,546,548,551],{"class":30,"data-line":547,"line":547},24,[28,549,550],{"class":41},"└──",[28,552,553],{"class":45}," readme.txt\n",[28,555,557],{"class":30,"data-line":556,"line":556},25,[28,558,56],{"emptyLinePlaceholder":55},[28,560,562,565,568,571],{"class":30,"data-line":561,"line":561},26,[28,563,564],{"class":41},"6",[28,566,567],{"class":45}," directories,",[28,569,570],{"class":75}," 17",[28,572,573],{"class":45}," files\n",[10,575,577],{"id":576},"安装go插件","安装Go插件",[246,579,580],{},"安装go对应的proto插件",[18,582,584],{"className":20,"code":583,"language":22,"meta":23,"style":23},"go install google.golang.org\u002Fprotobuf\u002Fcmd\u002Fprotoc-gen-go@latest\ngo install google.golang.org\u002Fgrpc\u002Fcmd\u002Fprotoc-gen-go-grpc@latest\n",[25,585,586,596],{"__ignoreMap":23},[28,587,588,591,593],{"class":30,"data-line":31,"line":31},[28,589,590],{"class":41},"go",[28,592,72],{"class":45},[28,594,595],{"class":45}," google.golang.org\u002Fprotobuf\u002Fcmd\u002Fprotoc-gen-go@latest\n",[28,597,598,600,602],{"class":30,"data-line":38,"line":38},[28,599,590],{"class":41},[28,601,72],{"class":45},[28,603,604],{"class":45}," google.golang.org\u002Fgrpc\u002Fcmd\u002Fprotoc-gen-go-grpc@latest\n",[246,606,607],{},"验证是否安装成功",[18,609,611],{"className":20,"code":610,"language":22,"meta":23,"style":23},"protoc-gen-go --version\nprotoc-gen-go-grpc --version\n",[25,612,613,621],{"__ignoreMap":23},[28,614,615,618],{"class":30,"data-line":31,"line":31},[28,616,617],{"class":41},"protoc-gen-go",[28,619,620],{"class":75}," --version\n",[28,622,623,626],{"class":30,"data-line":38,"line":38},[28,624,625],{"class":41},"protoc-gen-go-grpc",[28,627,620],{"class":75},[10,629,630],{"id":630},"oneof语法",[246,632,633,634,637,638,640],{},"在proto语法当中",[25,635,636],{"code":636},"oneof","关键字比较特殊，代表多选一\n实际上就是定义proto时不确定使用什么字段，设置",[25,639,636],{"code":636},"，本质上类似Go语法当中的枚举类型",[246,642,643],{},"举个例子",[246,645,646],{},"如果我的博客文章更新了，既可以选择短信推送也可以选择邮件推送",[246,648,649,650],{},"可以这样定义",[25,651,652],{"code":652},"proto",[18,654,657],{"className":655,"code":656,"language":652,"meta":23,"style":23},"language-proto shiki shiki-themes github-light github-dark","syntax = \"proto3\";\n\noption go_package=\"hello\u002Fpb;pb\";\n\npackage pb;\n\nmessage NoticeRequest {\n    string msg = 1;\n    oneof msg_type {\n        string phone = 2;\n        string email = 3;\n    }\n}\n\nmessage NoticeResponse {\n    string msg = 1;\n}\n\nservice NoticeService {\n    rpc Notice (NoticeRequest) returns (NoticeResponse);\n}\n",[25,658,659,673,677,692,696,706,710,725,744,756,774,792,801,805,809,820,834,838,842,854,891],{"__ignoreMap":23},[28,660,661,664,667,670],{"class":30,"data-line":31,"line":31},[28,662,663],{"class":100},"syntax",[28,665,666],{"class":100}," =",[28,668,669],{"class":45}," \"proto3\"",[28,671,672],{"class":96},";\n",[28,674,675],{"class":30,"data-line":38,"line":38},[28,676,56],{"emptyLinePlaceholder":55},[28,678,679,682,685,687,690],{"class":30,"data-line":52,"line":52},[28,680,681],{"class":100},"option",[28,683,684],{"class":75}," go_package",[28,686,101],{"class":100},[28,688,689],{"class":45},"\"hello\u002Fpb;pb\"",[28,691,672],{"class":96},[28,693,694],{"class":30,"data-line":59,"line":59},[28,695,56],{"emptyLinePlaceholder":55},[28,697,698,701,704],{"class":30,"data-line":65,"line":65},[28,699,700],{"class":100},"package",[28,702,703],{"class":45}," pb",[28,705,672],{"class":96},[28,707,708],{"class":30,"data-line":82,"line":82},[28,709,56],{"emptyLinePlaceholder":55},[28,711,712,715,718,721],{"class":30,"data-line":87,"line":87},[28,713,714],{"class":100},"message",[28,716,717],{"class":41}," NoticeRequest",[28,719,720],{"class":96}," ",[28,722,724],{"class":723},"sSDpw","{\n",[28,726,727,731,734,737,739,742],{"class":30,"data-line":93,"line":93},[28,728,730],{"class":729},"indent","    ",[28,732,733],{"class":100},"string",[28,735,736],{"class":96}," msg ",[28,738,101],{"class":100},[28,740,741],{"class":75}," 1",[28,743,672],{"class":96},[28,745,746,748,750,753],{"class":30,"data-line":107,"line":107},[28,747,730],{"class":729},[28,749,636],{"class":100},[28,751,752],{"class":96}," msg_type ",[28,754,724],{"class":755},"sJX2D",[28,757,758,760,762,764,767,769,772],{"class":30,"data-line":119,"line":119},[28,759,730],{"class":729},[28,761,730],{"class":729},[28,763,733],{"class":100},[28,765,766],{"class":96}," phone ",[28,768,101],{"class":100},[28,770,771],{"class":75}," 2",[28,773,672],{"class":96},[28,775,776,778,780,782,785,787,790],{"class":30,"data-line":124,"line":124},[28,777,730],{"class":729},[28,779,730],{"class":729},[28,781,733],{"class":100},[28,783,784],{"class":96}," email ",[28,786,101],{"class":100},[28,788,789],{"class":75}," 3",[28,791,672],{"class":96},[28,793,794,796,798],{"class":30,"data-line":130,"line":130},[28,795,730],{"class":729},[28,797,23],{"class":96},[28,799,800],{"class":755},"}\n",[28,802,803],{"class":30,"data-line":153,"line":153},[28,804,800],{"class":723},[28,806,807],{"class":30,"data-line":171,"line":171},[28,808,56],{"emptyLinePlaceholder":55},[28,810,811,813,816,818],{"class":30,"data-line":176,"line":176},[28,812,714],{"class":100},[28,814,815],{"class":41}," NoticeResponse",[28,817,720],{"class":96},[28,819,724],{"class":723},[28,821,822,824,826,828,830,832],{"class":30,"data-line":182,"line":182},[28,823,730],{"class":729},[28,825,733],{"class":100},[28,827,736],{"class":96},[28,829,101],{"class":100},[28,831,741],{"class":75},[28,833,672],{"class":96},[28,835,836],{"class":30,"data-line":476,"line":476},[28,837,800],{"class":723},[28,839,840],{"class":30,"data-line":486,"line":486},[28,841,56],{"emptyLinePlaceholder":55},[28,843,844,847,850,852],{"class":30,"data-line":496,"line":496},[28,845,846],{"class":100},"service",[28,848,849],{"class":41}," NoticeService",[28,851,720],{"class":96},[28,853,724],{"class":723},[28,855,856,858,861,864,866,869,872,875,877,880,882,884,887,889],{"class":30,"data-line":506,"line":506},[28,857,730],{"class":729},[28,859,860],{"class":100},"rpc",[28,862,863],{"class":41}," Notice",[28,865,720],{"class":96},[28,867,868],{"class":755},"(",[28,870,871],{"class":41},"NoticeRequest",[28,873,874],{"class":755},")",[28,876,720],{"class":96},[28,878,879],{"class":100},"returns",[28,881,720],{"class":96},[28,883,868],{"class":755},[28,885,886],{"class":41},"NoticeResponse",[28,888,874],{"class":755},[28,890,672],{"class":96},[28,892,893],{"class":30,"data-line":516,"line":516},[28,894,800],{"class":723},[246,896,897],{},"定义server端代码",[18,899,902],{"className":900,"code":901,"language":590,"meta":23,"style":23},"language-go shiki shiki-themes github-light github-dark","type NoticeServer struct {\n\tpb.UnimplementedNoticeServiceServer\n}\n\nfunc (s *NoticeServer) Notice(ctx context.Context, req *pb.NoticeRequest) (*pb.NoticeResponse, error) {\n\tsend_msg := req.Msg\n\tswitch req.MsgType.(type) { \u002F\u002F 类型断言\n\tcase *pb.NoticeRequest_Email:\n\t\tsend_msg += \" send by email:\" + req.GetEmail()\n\tcase *pb.NoticeRequest_Phone:\n\t\tsend_msg += \" send by phone\" + req.GetPhone()\n\t}\n\n\treturn &pb.NoticeResponse{\n\t\tMsg: send_msg,\n\t}, nil\n}\n",[25,903,904,919,933,937,941,1020,1033,1059,1078,1107,1124,1148,1156,1160,1178,1187,1201],{"__ignoreMap":23},[28,905,906,909,912,915,917],{"class":30,"data-line":31,"line":31},[28,907,908],{"class":100},"type",[28,910,911],{"class":41}," NoticeServer",[28,913,914],{"class":100}," struct",[28,916,720],{"class":96},[28,918,724],{"class":723},[28,920,921,924,927,930],{"class":30,"data-line":38,"line":38},[28,922,923],{"class":729},"\t",[28,925,926],{"class":41},"pb",[28,928,929],{"class":96},".",[28,931,932],{"class":41},"UnimplementedNoticeServiceServer\n",[28,934,935],{"class":30,"data-line":52,"line":52},[28,936,800],{"class":723},[28,938,939],{"class":30,"data-line":59,"line":59},[28,940,56],{"emptyLinePlaceholder":55},[28,942,943,946,948,950,954,957,960,962,964,967,969,972,975,977,980,983,986,989,991,993,995,997,999,1001,1003,1005,1007,1009,1011,1014,1016,1018],{"class":30,"data-line":65,"line":65},[28,944,945],{"class":100},"func",[28,947,720],{"class":96},[28,949,868],{"class":723},[28,951,953],{"class":952},"s4XuR","s ",[28,955,956],{"class":100},"*",[28,958,959],{"class":41},"NoticeServer",[28,961,874],{"class":723},[28,963,720],{"class":96},[28,965,966],{"class":41},"Notice",[28,968,868],{"class":723},[28,970,971],{"class":952},"ctx",[28,973,974],{"class":41}," context",[28,976,929],{"class":96},[28,978,979],{"class":41},"Context",[28,981,982],{"class":96},", ",[28,984,985],{"class":952},"req",[28,987,988],{"class":100}," *",[28,990,926],{"class":41},[28,992,929],{"class":96},[28,994,871],{"class":41},[28,996,874],{"class":723},[28,998,720],{"class":96},[28,1000,868],{"class":723},[28,1002,956],{"class":100},[28,1004,926],{"class":41},[28,1006,929],{"class":96},[28,1008,886],{"class":41},[28,1010,982],{"class":96},[28,1012,1013],{"class":100},"error",[28,1015,874],{"class":723},[28,1017,720],{"class":96},[28,1019,724],{"class":723},[28,1021,1022,1024,1027,1030],{"class":30,"data-line":82,"line":82},[28,1023,923],{"class":729},[28,1025,1026],{"class":96},"send_msg ",[28,1028,1029],{"class":100},":=",[28,1031,1032],{"class":96}," req.Msg\n",[28,1034,1035,1037,1040,1043,1045,1047,1049,1051,1054,1056],{"class":30,"data-line":87,"line":87},[28,1036,923],{"class":729},[28,1038,1039],{"class":100},"switch",[28,1041,1042],{"class":96}," req.MsgType.",[28,1044,868],{"class":755},[28,1046,908],{"class":100},[28,1048,874],{"class":755},[28,1050,720],{"class":96},[28,1052,1053],{"class":755},"{",[28,1055,720],{"class":96},[28,1057,1058],{"class":34},"\u002F\u002F 类型断言\n",[28,1060,1061,1063,1066,1068,1070,1072,1075],{"class":30,"data-line":93,"line":93},[28,1062,923],{"class":729},[28,1064,1065],{"class":100},"case",[28,1067,988],{"class":100},[28,1069,926],{"class":41},[28,1071,929],{"class":96},[28,1073,1074],{"class":41},"NoticeRequest_Email",[28,1076,1077],{"class":96},":\n",[28,1079,1080,1082,1084,1086,1089,1092,1095,1098,1101,1104],{"class":30,"data-line":107,"line":107},[28,1081,923],{"class":729},[28,1083,923],{"class":729},[28,1085,1026],{"class":96},[28,1087,1088],{"class":100},"+=",[28,1090,1091],{"class":45}," \" send by email:\"",[28,1093,1094],{"class":100}," +",[28,1096,1097],{"class":96}," req.",[28,1099,1100],{"class":41},"GetEmail",[28,1102,868],{"class":1103},"sqkie",[28,1105,1106],{"class":1103},")\n",[28,1108,1109,1111,1113,1115,1117,1119,1122],{"class":30,"data-line":119,"line":119},[28,1110,923],{"class":729},[28,1112,1065],{"class":100},[28,1114,988],{"class":100},[28,1116,926],{"class":41},[28,1118,929],{"class":96},[28,1120,1121],{"class":41},"NoticeRequest_Phone",[28,1123,1077],{"class":96},[28,1125,1126,1128,1130,1132,1134,1137,1139,1141,1144,1146],{"class":30,"data-line":124,"line":124},[28,1127,923],{"class":729},[28,1129,923],{"class":729},[28,1131,1026],{"class":96},[28,1133,1088],{"class":100},[28,1135,1136],{"class":45}," \" send by phone\"",[28,1138,1094],{"class":100},[28,1140,1097],{"class":96},[28,1142,1143],{"class":41},"GetPhone",[28,1145,868],{"class":1103},[28,1147,1106],{"class":1103},[28,1149,1150,1152,1154],{"class":30,"data-line":130,"line":130},[28,1151,923],{"class":729},[28,1153,23],{"class":96},[28,1155,800],{"class":755},[28,1157,1158],{"class":30,"data-line":153,"line":153},[28,1159,56],{"emptyLinePlaceholder":55},[28,1161,1162,1164,1167,1170,1172,1174,1176],{"class":30,"data-line":171,"line":171},[28,1163,923],{"class":729},[28,1165,1166],{"class":100},"return",[28,1168,1169],{"class":100}," &",[28,1171,926],{"class":41},[28,1173,929],{"class":96},[28,1175,886],{"class":41},[28,1177,724],{"class":755},[28,1179,1180,1182,1184],{"class":30,"data-line":176,"line":176},[28,1181,923],{"class":729},[28,1183,923],{"class":729},[28,1185,1186],{"class":96},"Msg: send_msg,\n",[28,1188,1189,1191,1193,1196,1198],{"class":30,"data-line":182,"line":182},[28,1190,923],{"class":729},[28,1192,23],{"class":96},[28,1194,1195],{"class":755},"}",[28,1197,982],{"class":96},[28,1199,1200],{"class":75},"nil\n",[28,1202,1203],{"class":30,"data-line":476,"line":476},[28,1204,800],{"class":723},[246,1206,1207,1208,1212],{},"根据传过来的值进行",[1209,1210,1211],"strong",{},"类型断言","后继续处理",[246,1214,1215],{},"定义client端代码",[18,1217,1219],{"className":900,"code":1218,"language":590,"meta":23,"style":23},"\u002F\u002F notice\nnoticeResp, err := noticeClient.Notice(ctx, &pb.NoticeRequest{Msg: *msg, MsgType: &pb.NoticeRequest_Phone{\n\tPhone: \"15811111111\",\n}})\nif err != nil {\n\tlog.Fatalf(\"failed to call Notice[phone]: %v\", err)\n}\nlog.Printf(\"Response: %s\", noticeResp.Msg)\n\nnoticeResp, err = noticeClient.Notice(ctx, &pb.NoticeRequest{Msg: *msg, MsgType: &pb.NoticeRequest_Email{\n\tEmail: \"email@codepzj.cn\",\n}})\nif err != nil {\n\tlog.Fatalf(\"failed to call Notice[email]: %v\", err)\n}\nlog.Printf(\"Response: %s\", noticeResp.Msg)\n",[25,1220,1221,1226,1272,1285,1293,1311,1336,1340,1362,1366,1406,1418,1426,1440,1461,1465],{"__ignoreMap":23},[28,1222,1223],{"class":30,"data-line":31,"line":31},[28,1224,1225],{"class":34},"\u002F\u002F notice\n",[28,1227,1228,1231,1233,1236,1238,1240,1243,1246,1248,1250,1252,1254,1257,1259,1262,1264,1266,1268,1270],{"class":30,"data-line":38,"line":38},[28,1229,1230],{"class":96},"noticeResp, err ",[28,1232,1029],{"class":100},[28,1234,1235],{"class":96}," noticeClient.",[28,1237,966],{"class":41},[28,1239,868],{"class":723},[28,1241,1242],{"class":96},"ctx, ",[28,1244,1245],{"class":100},"&",[28,1247,926],{"class":41},[28,1249,929],{"class":96},[28,1251,871],{"class":41},[28,1253,1053],{"class":755},[28,1255,1256],{"class":96},"Msg: ",[28,1258,956],{"class":100},[28,1260,1261],{"class":96},"msg, MsgType: ",[28,1263,1245],{"class":100},[28,1265,926],{"class":41},[28,1267,929],{"class":96},[28,1269,1121],{"class":41},[28,1271,724],{"class":1103},[28,1273,1274,1276,1279,1282],{"class":30,"data-line":52,"line":52},[28,1275,923],{"class":729},[28,1277,1278],{"class":96},"Phone: ",[28,1280,1281],{"class":45},"\"15811111111\"",[28,1283,1284],{"class":96},",\n",[28,1286,1287,1289,1291],{"class":30,"data-line":59,"line":59},[28,1288,1195],{"class":1103},[28,1290,1195],{"class":755},[28,1292,1106],{"class":723},[28,1294,1295,1298,1301,1304,1307,1309],{"class":30,"data-line":65,"line":65},[28,1296,1297],{"class":100},"if",[28,1299,1300],{"class":96}," err ",[28,1302,1303],{"class":100},"!=",[28,1305,1306],{"class":75}," nil",[28,1308,720],{"class":96},[28,1310,724],{"class":723},[28,1312,1313,1315,1318,1321,1323,1326,1329,1331,1334],{"class":30,"data-line":82,"line":82},[28,1314,923],{"class":729},[28,1316,1317],{"class":96},"log.",[28,1319,1320],{"class":41},"Fatalf",[28,1322,868],{"class":755},[28,1324,1325],{"class":45},"\"failed to call Notice[phone]: ",[28,1327,1328],{"class":75},"%v",[28,1330,287],{"class":45},[28,1332,1333],{"class":96},", err",[28,1335,1106],{"class":755},[28,1337,1338],{"class":30,"data-line":87,"line":87},[28,1339,800],{"class":723},[28,1341,1342,1344,1347,1349,1352,1355,1357,1360],{"class":30,"data-line":93,"line":93},[28,1343,1317],{"class":96},[28,1345,1346],{"class":41},"Printf",[28,1348,868],{"class":723},[28,1350,1351],{"class":45},"\"Response: ",[28,1353,1354],{"class":75},"%s",[28,1356,287],{"class":45},[28,1358,1359],{"class":96},", noticeResp.Msg",[28,1361,1106],{"class":723},[28,1363,1364],{"class":30,"data-line":107,"line":107},[28,1365,56],{"emptyLinePlaceholder":55},[28,1367,1368,1370,1372,1374,1376,1378,1380,1382,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402,1404],{"class":30,"data-line":119,"line":119},[28,1369,1230],{"class":96},[28,1371,101],{"class":100},[28,1373,1235],{"class":96},[28,1375,966],{"class":41},[28,1377,868],{"class":723},[28,1379,1242],{"class":96},[28,1381,1245],{"class":100},[28,1383,926],{"class":41},[28,1385,929],{"class":96},[28,1387,871],{"class":41},[28,1389,1053],{"class":755},[28,1391,1256],{"class":96},[28,1393,956],{"class":100},[28,1395,1261],{"class":96},[28,1397,1245],{"class":100},[28,1399,926],{"class":41},[28,1401,929],{"class":96},[28,1403,1074],{"class":41},[28,1405,724],{"class":1103},[28,1407,1408,1410,1413,1416],{"class":30,"data-line":124,"line":124},[28,1409,923],{"class":729},[28,1411,1412],{"class":96},"Email: ",[28,1414,1415],{"class":45},"\"email@codepzj.cn\"",[28,1417,1284],{"class":96},[28,1419,1420,1422,1424],{"class":30,"data-line":130,"line":130},[28,1421,1195],{"class":1103},[28,1423,1195],{"class":755},[28,1425,1106],{"class":723},[28,1427,1428,1430,1432,1434,1436,1438],{"class":30,"data-line":153,"line":153},[28,1429,1297],{"class":100},[28,1431,1300],{"class":96},[28,1433,1303],{"class":100},[28,1435,1306],{"class":75},[28,1437,720],{"class":96},[28,1439,724],{"class":723},[28,1441,1442,1444,1446,1448,1450,1453,1455,1457,1459],{"class":30,"data-line":171,"line":171},[28,1443,923],{"class":729},[28,1445,1317],{"class":96},[28,1447,1320],{"class":41},[28,1449,868],{"class":755},[28,1451,1452],{"class":45},"\"failed to call Notice[email]: ",[28,1454,1328],{"class":75},[28,1456,287],{"class":45},[28,1458,1333],{"class":96},[28,1460,1106],{"class":755},[28,1462,1463],{"class":30,"data-line":176,"line":176},[28,1464,800],{"class":723},[28,1466,1467,1469,1471,1473,1475,1477,1479,1481],{"class":30,"data-line":182,"line":182},[28,1468,1317],{"class":96},[28,1470,1346],{"class":41},[28,1472,868],{"class":723},[28,1474,1351],{"class":45},[28,1476,1354],{"class":75},[28,1478,287],{"class":45},[28,1480,1359],{"class":96},[28,1482,1106],{"class":723},[246,1484,1485],{},"可以定义phone和email两种不同的请求信息",[1487,1488,1489],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sSDpw, html code.shiki .sSDpw{--shiki-default:#005cc5;--shiki-dark:#79b8ff}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJX2D, html code.shiki .sJX2D{--shiki-default:#e36209;--shiki-dark:#ffab70}html pre.shiki code .sqkie, html code.shiki .sqkie{--shiki-default:#5a32a3;--shiki-dark:#b392f0}",{"title":23,"searchDepth":59,"depth":59,"links":1491},[1492,1496,1497,1498],{"id":12,"depth":38,"text":12,"children":1493},[1494,1495],{"id":16,"depth":52,"text":16},{"id":194,"depth":52,"text":194},{"id":302,"depth":38,"text":303},{"id":576,"depth":38,"text":577},{"id":630,"depth":38,"text":630},[1500],"微服务","2025-09-15","介绍 protoc 的命令行安装方式、环境变量配置，以及 Go 代码生成插件的安装与验证。",false,"md",null,{"slots":1507},{},"\u002F2025\u002F09\u002Fproto-install",{"text":1510,"minutes":1511,"time":1512,"words":1513},"3 min read",2.57,154200,514,{"title":5,"description":1502},{"loc":1508},"posts\u002F2025\u002F09\u002Fproto-install",[1518,1500],"gRPC","tech","2025-12-10","5sPLjm5c91EPBTiav_wLVbmt82YZl4YRCivsAzaQUXM",[1523,1528],{"title":1524,"path":1525,"stem":1526,"date":1527,"type":1519,"children":-1},"Redis String 常用命令","\u002F2025\u002F09\u002Fredis-string-command","posts\u002F2025\u002F09\u002Fredis-string-command","2025-09-10",{"title":1529,"path":1530,"stem":1531,"date":1532,"type":1519,"children":-1},"docker部署mysql中文乱码问题","\u002F2025\u002F09\u002Fdocker-mysql-charset-problem","posts\u002F2025\u002F09\u002Fdocker-mysql-charset-problem","2025-09-17",1786555055349]