{"id":1146,"date":"2022-08-18T12:01:22","date_gmt":"2022-08-18T04:01:22","guid":{"rendered":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146"},"modified":"2022-09-04T11:51:10","modified_gmt":"2022-09-04T03:51:10","slug":"go-118generic-and-fuzz","status":"publish","type":"post","link":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146","title":{"rendered":"Go 1.18:Generic and Fuzz"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">\u932f\u8aa4\u7684\u7a2e\u985e<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u8b1b\u9019\u500b\u4e4b\u524d\uff0c\u5148\u63d0\u4e00\u4e0b\u4e3b\u6d41\u8a9e\u8a00\u901a\u5e38\u300c\u932f\u8aa4\u6aa2\u51fa\u300d\u65b9\u9762\u901a\u5e38\u5206\u70ba\u4e09\u500b\u968e\u6bb5\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u7de8\u8b6f\u524d\u968e\u6bb5 (pre-compile time)<br><ul><li>\u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u4e0d\u9700\u8981\u88ab\u7de8\u8b6f\u5373\u53ef\u88ab\u6aa2\u51fa<\/li><li>\u5f88\u591a\u8a9e\u8a00\u6c92\u6709\u9019\u6771\u897f\uff0c\u4ed6\u9700\u8981language server protocol(LSP)\u652f\u63f4\uff0c\u5982<code>gopls<\/code><\/li><li>\u5f88\u591aIDE\u5404\u8a9e\u8a00\u7684\u8ce3\u9ede\u5c31\u662f\u81ea\u5df1\u7368\u5230\u7684LSP\uff0c\u4f46\u662f\u525b\u597d\u62ff\u4f86\u505a\u5229\u5b50\u7684<code>C++<\/code>\u64c1\u6709\u975e\u5e38\u6df7\u4e82\u7684LSP\u5be6\u4f5c\uff0c\u5e38\u5e38pre-compile time\u5831\u932f\uff0c\u4f46\u662fcompile\u4e0b\u53bb\u6c92\u554f\u984c\uff0c\u4ee5\u53ca\u53cd\u4e4b&#8230;.\u4e3b\u8981\u4e5f\u662f\u56e0\u70ba<code>C++<\/code>\u5be6\u5728\u662f\u904e\u65bc\u8907\u96dc\u3002<\/li><\/ul><\/li><li>\u7de8\u8b6f\u968e\u6bb5 (compile time)<br><ul><li>\u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u5728\u7de8\u8b6f\u7684\u6642\u5019\u5c31\u53ef\u4ee5\u627e\u51fa\u4f86<\/li><li>\u524d\u5169\u8005\u4e5f\u53ef\u4ee5\u4e26\u7a31\u70bacompile time\uff0c\u5982\u679c\u6c92\u6709\u8981\u7279\u5225\u6307\u540dLSP\u63d0\u4f9b\u7684\u529f\u80fd\u7684\u8a71\u3002<\/li><\/ul><\/li><li>\u57f7\u884c\u968e\u6bb5 (runtime)<br><ul><li>\u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u9700\u8981\u5728\u57f7\u884c\u671f\u624d\u6703\u767c\u4f5c<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u800cgo\u662f\u4e00\u500b\u6eff\u7279\u6b8a\u7684\u8a9e\u8a00\uff0c\u4ed6\u80fd\u5920\u628a\u4e00\u4e9bruntime\u624d\u80fd\u6aa2\u51fa\u7684\u6771\u897f\u85c9\u7531<code>gopls<\/code>\u4ee5\u53ca<code>go vet<\/code> \u505a\u7d50\u69cb\u6027\u8a9e\u6cd5\u6aa2\u67e5\u4e0b\uff0c\u5c07\u932f\u8aa4\u628aruntime\u63d0\u524d\u5230pre-compile time\u3002<\/p>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\"><code>type A string<\/code>\u4ee5\u53ca<code>type A = string<\/code>\u7684\u5dee\u7570<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728go source code\u88e1\u9762\uff0cany\u5176\u5be6\u5c31\u662f<code>interface{}<\/code>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type any = interface{}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5f88\u591a\u4eba\u6703\u6709\u500b\u7591\u554f\uff0c\u9019\u8ddf\u9019\u4ee5\u4e0b\u7684code\u6709\u5565\u4e0d\u540c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type any interface{}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u5011\u53ef\u4ee5\u7528\u4e0b\u9762\u9019\u7d44code\u770b\u51fa\u5dee\u7570\u5728\u54ea<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type Foo int\ntype Foo2 = int\n\nfunc (f *Foo) Method() { \/\/\u9019\u500b\u6c92\u554f\u984c\n\t\n}\n\nfunc (f2 *Foo2) Method() { \/\/\u9019\u884c\u7de8\u8b6f\u5668\u5c31\u6703\u5831\u932f\u4e86\n\t\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7c21\u55ae\u7684\u8aaa\uff0c\u7b2c\u4e00\u7a2e\u5beb\u6cd5\u662f<strong>\u5ba3\u544aFoo\u57fa\u5e95\u578b\u614b\u70baint\uff0c\u4e14\u53ef\u4ee5\u64f4\u5c55<\/strong>\uff0c\u7b2c\u4e8c\u7a2e\u5beb\u6cd5\u662f<strong>Foo\u5c31\u662fint\u7684\u5225\u7a31<\/strong>\uff0c\u5169\u8005\u610f\u7fa9\u4e0a\u662f\u4e0d\u540c\u7684\u3002\uff08\u5370\u8c61\u4e2d\uff09\u9019\u7a2e\u5beb\u6cd5\u7684\u5dee\u7570\u4e5f\u662f1.18\u7248\u624d\u958b\u59cb\u6709\u7684\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Constraints<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u8981\u719f\u6089Generic\uff0c\u9996\u5148\u8981\u5148\u7406\u89e3<code>constraints<\/code>\u9019\u500b\u65b0\u6982\u5ff5\u3002\u5982\u679c\u6709\u5beb\u904eCPP\u7684\u540c\u5b78\u61c9\u8a72\u5c0d\u4ee5\u4e0b\u9019\u6bb5code\u5f88\u719f\u6089\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">template &lt;class T&gt;\nint compute_length(T *value)\n{\n    return value-&gt;length();\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u800c<code>C++<\/code>\u4f86\u8b1b\u76f4\u5230<code>concept<\/code>\u5728<code>C++20<\/code>\u7248\u672c\u51fa\u73fe\u524d\uff0c\u662f\u6c92\u6709constraint\u7684\uff0c\u5373\u4f7f\u662f<code>concept<\/code>\u4e5f\u662f\u7528\u4e00\u7a2e\u6bd4\u8f03\u622a\u7136\u4e0d\u540c\u7684\u96b1\u6666\u65b9\u6cd5\u4f86\u505a<code>type constraint<\/code>\uff0c\u9019\u9ede\u5148\u8868\u904e\u4e0d\u8ac7\u3002\u5728\u6c92constraint\u7684\u60c5\u6cc1\u4e0b\uff0c\u9019\u6bb5code\u5176\u5be6\u5728\u7de8\u8b6f\u7684\u671f\u9593\u4e0d\u6703\u6aa2\u67e5\uff0c\u53ea\u6709\u5728\u771f\u6b63\u5be6\u9ad4\u5316\u7528\u4ed6\u7684\u6642\u5019\u624d\u6703\u505a\u7de8\u8b6f\u6aa2\u67e5\uff0c\u5982\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">class someClass1 {\n}; \/\/\u6c92\u6709int length()\u65b9\u6cd5\n\nclass someClass2 {\n\tint length()\n};\n\nsc1 = new someClass1();\nsc2 = new someClass2();\n\ncompute_length(sc1); \/\/\u7de8\u8b6f\u9019\u884c\u7684\u6642\u5019\u6703\u51fa\u932f\u4e26\u4e14\u5674\u51fa\u4e00\u5806\u770b\u4e0d\u61c2\u7684error\ncompute_length(sc2); \/\/\u6c92\u554f\u984c\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u90a3\u540c\u6a23\u7684\u6771\u897f\u5728golang\u6703\u662f\u9019\u6a23<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type Countable interface {\n\tlength() int\n}\n\nfunc computeLength[T Countable](value *T) int {\n\treturn value.length()\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u800c\u9019\u500b\u6703\u5728\u7de8\u8b6f\u671f\u5c31\u6703\u6aa2\u67e5\u76ee\u6a19\u6709\u6c92\u6709satisfy interface\uff0c\u5982<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type someStruct1 struct {} \/\/\u4e0dsatisify Countable\ntype someStruct2 struct {} \/\/Satisify Countable\nfunc (s *someStruct2) length() int {\n\treturn 0\n}\n\ncomputeLength(&amp;someStruct1{}) \/\/pre-compile time error\ncomputeLength(&amp;someStruct2{}) \/\/OK!\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7576\u7136\uff0c\u6240\u6709\u7684struct\u90fdsatisfy <code>interface{}<\/code>\uff0c\u4e0b\u9762\u6703\u63d0\u5230\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u6700\u7c21\u55ae\u7684Generic<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5927\u591a\u6578\u60c5\u6cc1\u4f86\u8b1b\uff0c\u6700\u5e38\u898b\u7684\u5c31\u662f\u5ba3\u544a<em>constraint\u70baany<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func GenericFunc[T any](input T) T {\n\treturn input\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u908a\u7684<code>any<\/code>\u5176\u5be6\u5c31\u662f\u5927\u5bb6\u7684\u8001\u76f8\u597d<code>interface{}<\/code>\u7684\u99ac\u7532\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">\/\/ in builtin.go:\n\/\/ any is an alias for interface{} and is equivalent to interface{} in all ways.\ntype any = interface{}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u524d\u9762\u6709\u63d0\u904e\u9019\u500b\u7b49\u865f\u662f\u5e79\u561b\u7684\uff0c\u6240\u4ee5\u9019\u500bany\u4e00\u6574\u500b\u5176\u5be6\u5c31\u662f <code>interface{}<\/code>\u7684\u5225\u7a31\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Primitive type constraints<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u518d\u4f86\u5c31\u662f\u5957<em>constraint<\/em>\u7684generic\uff0c\u57fa\u672c\u4e0aconstraint\u53ef\u4ee5\u662fprimitive type\u4e5f\u53ef\u4ee5\u662f<code>interface{}<\/code>\uff0c\u800c\u4e14\u662fUnion\u3002\u5148\u5f9eprimitive type\u770b\u8d77<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func GF[T int](){\t\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u500b\u662f\u6700\u7c21\u55ae\u7684\uff0c\u5f8c\u9762\u9084\u53ef\u4ee5\u6709\u4e9b\u8b8a\u5316\u5982<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func GF[T int | int8 | int16 | int32 | int64](){\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u751a\u81f3\u9084\u53ef\u4ee5\u628aconstraint union\u5beb\u6210\u4e00\u7a2etype\uff0c\u5982<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type IntConstraint interface {\n\tint | int8 | int16 | int32 | int64\n}\n\nfunc GF[T IntConstraint]() {\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e8b\u5be6\u4e0a\u76ee\u524d\u6709\u4e00\u500bpackage\u53eb\u505a<code>golang.org\/x\/exp\/constraints<\/code>\u88e1\u9762\u6709\u6eff\u591a\u5be6\u7528\u7684constraints\u3002\u4e0d\u904e\u4f7f\u7528X exp package\u662f\u6709\u98a8\u96aa\u7684\uff08\u4e0b\u9762\u6703\u8209\u4e00\u500b\u6d3b\u751f\u751f\u7684\u4f8b\u5b50\uff09<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">\/\/ Copyright 2021 The Go Authors. All rights reserved.\n\/\/ Use of this source code is governed by a BSD-style\n\/\/ license that can be found in the LICENSE file.\n\n\/\/ Package constraints defines a set of useful constraints to be used\n\/\/ with type parameters.\npackage constraints\n\n\/\/ Signed is a constraint that permits any signed integer type.\n\/\/ If future releases of Go add new predeclared signed integer types,\n\/\/ this constraint will be modified to include them.\ntype Signed interface {\n\t~int | ~int8 | ~int16 | ~int32 | ~int64\n}\n\n\/\/ Unsigned is a constraint that permits any unsigned integer type.\n\/\/ If future releases of Go add new predeclared unsigned integer types,\n\/\/ this constraint will be modified to include them.\ntype Unsigned interface {\n\t~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr\n}\n\n\/\/ Integer is a constraint that permits any integer type.\n\/\/ If future releases of Go add new predeclared integer types,\n\/\/ this constraint will be modified to include them.\ntype Integer interface {\n\tSigned | Unsigned\n}\n\n\/\/ Float is a constraint that permits any floating-point type.\n\/\/ If future releases of Go add new predeclared floating-point types,\n\/\/ this constraint will be modified to include them.\ntype Float interface {\n\t~float32 | ~float64\n}\n\n\/\/ Complex is a constraint that permits any complex numeric type.\n\/\/ If future releases of Go add new predeclared complex numeric types,\n\/\/ this constraint will be modified to include them.\ntype Complex interface {\n\t~complex64 | ~complex128\n}\n\n\/\/ Ordered is a constraint that permits any ordered type: any type\n\/\/ that supports the operators &lt; &lt;= &gt;= &gt;.\n\/\/ If future releases of Go add new ordered types,\n\/\/ this constraint will be modified to include them.\ntype Ordered interface {\n\tInteger | Float | ~string\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u95dc\u65bc <code>~<\/code> \u662f\u5565\u610f\u601d\u53ef\u4ee5\u53c3\u8003<a href=\"https:\/\/github.com\/akutz\/go-generics-the-hard-way\/blob\/main\/03-getting-started\/06-tilde.md\">\u9019\u4e00\u7bc7<\/a>\u3002\u7c21\u55ae\u7684\u8aaa\u5c31\u662f\u8b93\u4ed6\u9069\u7528\u65bc\u6240\u6709\u884d\u751f\u578b\u5225\u3002\u884d\u751f\u578b\u5225\u5c31\u662f\u6211\u524d\u9762\u63d0\u5230\u7684<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type A string\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u90a3constraint\u8981\u662f\u6253 <code>~string<\/code>\u7684\u8a71\uff0c<code>A<\/code>\u4e5f\u7b97\u662f\u5408\u4e4e\u689d\u4ef6\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u66f4\u591a\u95dc\u65bcX exp package\u4ee5\u53caRC Release\u7684\u98a8\u96aa\uff0c\u4ee5\u53ca\u70ba\u5565\u9019\u500b\u65b9\u4fbf\u5305\u88ab\u4e1f\u9032\u53bb\uff0c\u53ef\u4ee5\u770b<a href=\"https:\/\/segmentfault.com\/a\/1190000041364494\">\u9019\u4e00\u7bc7<\/a>\u7684\u8aaa\u660e\u3002\u53e6\u5916\u518d\u5f37\u8abf\u4e00\u6b21\uff0c\u6709\u98a8\u96aa\u7684\u50c5\u6b62\u65bc<em>X EXP Package<\/em>\uff0c\u5176\u4ed6\u7684X Package\u90fd\u53ef\u4ee5\u5b89\u5fc3\u4f7f\u7528\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">interface type constraint<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u8003\u616e\u4e00\u4e0b\u4ee5\u4e0b\u7684code\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type TypeA interface {\n\tA()\n}\n\ntype TypeB interface {\n\tB()\n\tC()\n}\n\nfunc GF1[T TypeA](t T) { \/\/OK!\n\tt.A()\n}\n\nfunc GF2[T TypeB](t T) { \/\/OK!\n\tt.C()\n\tt.B()\n}\n\nfunc GF3[T TypeA | TypeB](t T){ \/\/Error: can't use interface with methods in union\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5373\u4f7f\u662f\u5169\u500b\u6709\u5171\u4eab\u7684Method\u4e5f\u4e0d\u884c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type TypeA interface {\n\tA()\n\tB()\n}\n\ntype TypeB interface {\n\tB()\n\tC()\n}\n\nfunc GF3[T TypeA | TypeB](t T){ \/\/Error: can't use interface with methods in union\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u8981\u7528\u4e00\u7a2e\u5f88\u7279\u6b8a\u7684\u89e3\u6cd5\u3002\u5148\u628aTypeA\/TypeB\u5ba3\u544a\u6210struct\uff0c\u5206\u5225\u4f5c\u51famethod\u5f8c\uff0c\u628a\u4ed6\u653e\u5728constraint union\u88e1\u9762\u5ba3\u544a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type TypeA struct {\n\t\/\/\u6709\u4ee5\u4e0b\u5be6\u4f5c\n\t\/\/A()\n\t\/\/B()\n\t\/\/Other()\n}\n\ntype TypeB struct {\n\t\/\/\u6709\u4ee5\u4e0b\u5be6\u4f5c\n\t\/\/B()\n\t\/\/C()\n\t\/\/Other()\n}\n\ntype TypeAB interface {\n\t*TypeA|*TypeB\n\tB()\n}\n\nfunc GF3[T TypeAB](t T) {\n\tt.B() \/\/\u5c31\u50c5\u6709B\u80fd\u7528\uff0c\u5373\u4f7f\u662fOther()\u4e5f\u662f\u5171\u901a\uff0c\u4f46\u662f\u6c92\u5ba3\u544a\u6545\u7121\u6cd5\u4f7f\u7528\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0d\u904e\u8001\u5be6\u8b1b\u57281.18\u88e1\u9762generic\/constraint\u8a9e\u6cd5\u4e26\u6c92\u6709\u5f88\u5b8c\u5584\u7684\u60c5\u6cc1\u4e0b\uff0c\u9664\u975e\u771f\u7684\u6709\u4ec0\u9ebc\u4e0d\u5f97\u4e86\u7684\u7528\u9014\u975e\u5f97\u9019\u6a23\u73a9\u4e0d\u53ef\uff0c\u6211\u6703\u5be7\u53ef\u653e\u68c4generic\u4f86\u5beb\u5169\u7d44code\u5206\u5225\u5c0d\u61c9<code>TypeA<\/code>\u4ee5\u53ca<code>TypeB<\/code>&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u6709\u8208\u8da3\u7684\u540c\u5b78\u53ef\u4ee5<a href=\"https:\/\/stackoverflow.com\/questions\/71376627\/in-go-generics-how-to-use-a-common-method-for-types-in-a-union-constraint\">\u8b80\u8b80\u9019\u4e00\u7bc7<\/a>\uff0c\u88e1\u9762\u4f5c\u8005\u6709\u975e\u5e38\u8a73\u7d30\u7684\u89e3\u91cb\u4ed6\u7684\u539f\u7406\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u5be6\u4f8b\uff1a\u4e0d\u540c\u578b\u614b\u7684slice\u4e4b\u9593\u4e92\u8f49<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u5011\u5148\u5047\u8a2d\u4e00\u4e0b\u6211\u5011\u6709\u500btype\u9577\u9019\u6a23 (\u6c92\u8fa6\u6cd5\uff0cgolang\u7684enum\u5c31\u662f\u4e0d\u641e\u597d\uff09<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">type DeployTarget string\n\nconst (\n\tDeployTargetDev  DeployTarget = \"dev\"\n\tDeployTargetQA   DeployTarget = \"qa\"\n\tDeployTargetProd DeployTarget = \"prod\"\n)\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u5011\u9700\u8981\u628a\u9019\u500b\u6771\u897f\u7576\u4f5cquery parameter\u50b3\u7d66api\u7aef\uff0c\u6bd4\u8f03\u5e38\u898b\u7684\u5beb\u6cd5\u5c31\u662f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">targets := []DeployTarget{DeployTargetDev, DeployTargetQA, DeployTargetProd}\n\t\nvalues := url.Values{\n\t\tDeployTargetQueryParamKey: targets, \/\/\u5831\u932f\uff0c\u4ed6\u53ea\u5403[]string\n\t}\n\n\/\/\u7136\u5f8curl\u5f80\u4e0b\u50b3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u986f\u7136\uff0c\u6211\u5011\u9700\u8981\u4e00\u500b\u65b9\u6cd5\u80fd\u5920\u628a<code>[]DeployTarget<\/code>\u8f49\u6210<code>[]string<\/code>\u3002\u771f\u7684\u8981\u7279\u5730\u70ba<code>DeployTarget<\/code>\u5beb\u4e00\u500b\u8f49\u63dbslice\u4e5f\u4e0d\u96e3\uff0c\u4f46\u662f\u9019\u7a2ecase\u4e00\u591a\uff0c\u7e3d\u6703\u5e0c\u671b\u8981\u8f49\u4e58Generic\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e2d\u9593\u601d\u8def\u5c31\u4e0d\u5beb\u4e86\uff0c\u76f4\u63a5\u8aaa\u7d50\u679c\u3002\u5176\u5be6\u7528\u719f\u4e86\u4e0d\u81ea\u5df1\u60f3\u51fa\u4f86\uff08\u6211\u4e5f\u662f\u5728\u505aSDK\u904e\u7a0b\u4e2d\u82b1\u5341\u5206\u9418\u62fc\u51fa\u4f86\u7684\uff09<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">\n\ntype Castable[T any] interface {\n\tCastTo() T\n}\n\n\/\/\u8b93DeployTarget\u80fdconfort Castable interface\nfunc (d DeployTarget) CastTo() string {\n\treturn string(d)\n}\n\n\/\/\u8981\u8b93DeployTarget\u80fdCast\u6210string\uff0c\u6240\u4ee5T\u70baDeployTarget, U\u70bastring\nfunc CastSlice[T Castable[U], U any](from []T) []U {\n\tto := make([]U, len(from))\n\tfor i, v := range from {\n\t\tto[i] = v.CastTo()\n\t}\n\treturn to\n}\n\n\/\/\u4f7f\u7528\u65b9\u6cd5 \nfunc TestFunc(targets []DeployTarget) {\n\tvalues := url.Values{\n\t\tDeployTargetQueryParamKey: CastSlice[DeployTarget, string](targets),\n\t}\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7576\u7136\u4e0d\u898b\u5f97\u8981\u8f49<code>string<\/code>\uff0c\u4f60\u53ea\u8981implement <code>CastTo() T<\/code> \u4f60\u8981\u8f49\u6210int\u4e5f\u6210&#8230; \u5e0c\u671b\u9019\u500b\u80fd\u8b93\u4f60\u5011\u89ba\u5f97\u300c\u54c7\u9760\uff0c\u5c45\u7136\u80fd\u9019\u6a23\u7528\uff0cgeneric\u5305generic!\u300d\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u9650\u5236<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6709receiver\u7684func (\u5373<code>func (s *someStruct) foo()<\/code>\u4e4b\u985e\uff0c\u6216\u7a31<em>method<\/em>\uff09\u7121\u6cd5\u4f7f\u7528generic\u3002\u9019\u500b\u9650\u5236\u5176\u6642\u662f\u6709\u9ede\u722d\u8ad6\u7684\uff0c\u5f88\u591a\u4eba\u6015\u8981\u662f\u958b\u653e\u9019\u7a2e\u6771\u897f\uff0c\u5c07\u6703\u5c0e\u81f4golang<a href=\"https:\/\/www.sobyte.net\/post\/2022-01\/go-generic-supports-specialization-no\/\">\u91cd\u6f14CPP\u7684template\u60e1\u5922<\/a>\u3002\u5982\u679c\u4f60\u4e0d\u60f3\u8981\u770b\u5230\u4e00\u5806\u4ec0\u9ebc\u504f\u7279\u5316\u554a\uff0c\u6307\u5b9a\u7279\u5316\u554a\u5728go\u7684\u672a\u4f86\u8ddf\u4f60\u62db\u624b\u7684\u8a71\uff0c\u9019\u662f\u4e00\u500b\u5f88\u597d\u7684\u53c3\u8003\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0d\u904e\u5c0d\u6211\u9019\u500b\u7fd2\u6163STL\u7684\u4eba\u4f86\u8b1b\uff0c\u9019\u500b\u7e3d\u89ba\u5f97\u6709\u9ede&#8230;.\u9694\u9774\u6414\u7662\u7684feel\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">slices \/ maps\u7684\u652f\u63f4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>\u8acb\u6ce8\u610f\uff0c\u9019\u5169\u500b\u54e5\u5006\u597dpackage\u5728RC\u624d\u525b\u904e\u6c92\u591a\u4e45\uff0c\u5c31\u5728\u6b63\u5f0f\u7248\u88e1\u9762\u88ab\u4e1f\u5230X exp Packages\u4e86\uff0cuse with caution<\/em><\/strong><em><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u9644\u5e36\u4e00\u63d0\uff0c\u5176\u5be6\u9019\u5169\u500bpackage\u90fd\u6c92\u5565\u554f\u984c\uff0c\u4e4b\u6240\u4ee5\u88ab\u6253\u9032exp package\u662f\u56e0\u70ba\u4ed6\u5f15\u7528\u4e86<a href=\"golang.org\/x\/exp\/constraints\">golang.org\/x\/exp\/constraints<\/a>\uff0c\u7b97\u662f\u6709\u5920\u8870\u5c0f\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u88e1\u9762\u5176\u5be6\u5c31\u662f\u4e00\u4e9b\u6211\u5011\u5e73\u5e38\u5c31\u6703\u5beb\u7684utility\u3002\u6bd4\u65b9\u8aaa\u5728\u6c92\u6709generic\u4ee5\u524d\uff0c\u6211\u5011\u8981\u627e\u67d0\u500bstring\u5728slice\u88e1\u9762\u7684index\u5927\u6982\u90fd\u6703\u9019\u6a23\u5beb<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func Index(s []string, v string) int {\n\tfor i, vs := range s {\n\t\tif v == vs {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc main() {\n\ts := []string{\"a\", \"b\", \"c\"}\n\tfmt.Println(Index(s, \"b\"))\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u5169\u500b\u5305\u5927\u6982\u7387\u90fd\u662f\u5e6b\u4f60\u7528\u9019\u4e9b\u770b\u8d77\u4f86\u6a38\u5be6\u7121\u83ef\u4e14\u5be6\u7528\u7684\u65b9\u6cd5\uff0c\u4ee5generic\u5e6b\u4f60\u5be6\u73fe\u800c\u5df2\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func Index[E comparable](s []E, v E) int {\n\tfor i, vs := range s {\n\t\tif v == vs {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7136\u5f8c\u8b93\u4f60\u53ef\u4ee5\u9019\u6a23\u7528<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func main() {\n\ts := []string{\"a\", \"b\", \"c\"}\n\tfmt.Println(slices.Index(s, \"b\"))\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u53ef\u4ee5\u53c3\u8003\u4e00\u4e0b\u9019\u5169\u500b\u5305\u6709\u54ea\u4e9b\u5de5\u5177\u80fd\u7528<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/pkg.go.dev\/golang.org\/x\/exp@v0.0.0-20220722155223-a9213eeb770e\/slices\">slices package<\/a><\/li><li><a href=\"https:\/\/pkg.go.dev\/golang.org\/x\/exp@v0.0.0-20220722155223-a9213eeb770e\/maps\">maps package<\/a><br><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u4f46\u662f\u5c37\u5c2c\u7684\u662f\u4ed6\u5011\u662fX exp package\uff0c\u6240\u4ee5\u5565\u6642\u6703\u88ab\u653e\u56de\u53bb\u4e5f\u4e0d\u77e5\u9053\uff0c\u6240\u4ee5&#8230;.\u597d\u5427\uff0c\u5c31\u662f\u5c37\u5c2c\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fuzz Test<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fuzz Test\u5c31\u662f\u6a21\u7cca\u6e2c\u8a66\uff0c\u7c21\u55ae\u7684\u8aaa\u5c31\u662f\u5229\u7528\u4e82\u6578\u8f38\u5165\u6e2c\u8a66\u53c3\u6578\u8dd1\u5f88\u591a\u6b21\uff0c\u4f86\u78ba\u5b9a\u7d50\u679c\u662f\u6b63\u78ba\u7684\u3002\u9019\u53ef\u4ee5\u6e2c\u51fa\u5982boundary overflow\u7b49\u666e\u901a\u6e2c\u8a66\u4e0d\u5bb9\u6613\u6e2c\u51fa\u7684\u554f\u984c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fuzz Test\u57fa\u672c\u4e0a\u90fd\u662f\u8ddf\u696d\u52d9\u908f\u8f2f\u9ad8\u5ea6\u76f8\u95dc\uff0c\u6eff\u96e3\u5beb\u7684 XD \u6240\u4ee5\u6211\u76f4\u63a5\u5f9e\u7db2\u8def\u4e0a\u6284\u4e00\u500b\u3002\u5047\u8a2d\u6211\u5011\u6709\u4e00\u500b\u51fd\u6578\uff0c\u4ed6\u8981\u628a\u5b57\u4e32\u7d66\u5012\u8f49\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func Rev(s string) string {\n\tbs := []byte(s)\n\tlength := len(bs)\n\tfor i := 0; i &lt; length\/2; i++ {\n\t\tbs[i], bs[length-i-1] = bs[length-i-1], bs[i]\n\t}\n\treturn string(bs)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5148\u4e0d\u7ba1\u9019\u908f\u8f2f\u6709\u6c92\u6709\u7455\u75b5\uff08\u6211\u5011\u5c31\u662f\u8981\u6e2c\u51fa\u7455\u75b5\u554a\uff09\uff0c\u9019\u500b\u51fd\u6578\u770b\u8d77\u4f86\u662f\u6c92\u554f\u984c\u7684\u3002\u6bd4\u65b9\u8aaa\u6211\u5011\u5beb\u4e00\u500b\u6a19\u6e96table test<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func TestRev(t *testing.T) {\n\ttype args struct {\n\t\ts string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Happy Path1\",\n\t\t\targs: args{\n\t\t\t\ts: \"abcde\",\n\t\t\t},\n\t\t\twant: \"edcba\",\n\t\t},\n\t\t{\n\t\t\tname: \"Happy Path2\",\n\t\t\targs: args{\n\t\t\t\ts: \"abcdef\",\n\t\t\t},\n\t\t\twant: \"fedcba\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Rev(tt.args.s); got != tt.want {\n\t\t\t\tt.Errorf(\"Rev() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u770b\u8d77\u4f86<code>abcde<\/code>\u8ddf<code>abcdef<\/code>\u90fd\u6c92\u5565\u554f\u984c\uff0c\u500b\u6578\u6709\u5947\u6578\u6709\u5076\u6578\uff0c\u770b\u8d77\u4f86\u90fdcover\u5230\u5566\uff0c\u9019\u500b<code>Rev()<\/code>\u770b\u4f86OK!\u904e\u95dc\uff01<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u7136\u800c\u6211\u5011\u7528Fuzz Test\u6e2c\u4e00\u6b21&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">func FuzzRev(f *testing.F) {\n\tstr_slice := []string{\"abc\", \"bb\"}\n\tfor _, v := range str_slice {\n\t\tf.Add(v)\n\t}\n\tf.Fuzz(func(t *testing.T, str string) {\n\t\t\/\/\u57fa\u672c\u539f\u7406\u5c31\u662f\uff0c\u7406\u8ad6\u4e0a\u4f60\u5169\u6b21\u53cd\u8f49\u4ee5\u5f8c\uff0c\u61c9\u8a72\u8981\u8f49\u56de\u539f\u672c\u7684\u5b57\u4e32\u3002\n\t\trev_str1 := Rev(str)\n\t\trev_str2 := Rev(rev_str1)\n\t\tif str != rev_str2 {\n\t\t\tt.Errorf(\"fuzz test failed. str:%s, rev_str1:%s, rev_str2:%s\", str, rev_str1, rev_str2)\n\t\t}\n\t\tif utf8.ValidString(str) &amp;&amp; !utf8.ValidString(rev_str1) {\n\t\t\tt.Errorf(\"reverse result is not utf8. str:%s, len: %d, rev_str1:%s\", str, len(str), rev_str1)\n\t\t}\n\t})\n\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8a92\uff0c\u5831\u932f\u4e86\uff0c\u6211\u5011\u770b\u4e00\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">fuzz: elapsed: 0s, gathering baseline coverage: 2\/5 completed\n--- FAIL: FuzzRev (0.03s)\n    --- FAIL: FuzzRev (0.00s)\n        fuzz_test.go:20: reverse result is not utf8. str:0\u0614, len: 3, rev_str1:\ufffd\ufffd0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6069\uff0c\u5728\u8f38\u5165\u70ba<code>0\u0614, <\/code>\u7684\u6642\u5019\u9019\u500b\u6703\u6709\u554f\u984c\u3002\u5982\u679c\u8981\u66f4\u6df1\u5c64\u6b21\u8ffd\u7a76\u7684\u8a71\uff0c\u5c31\u8981\u628a\u9019\u7d44hex\u5370\u51fa\u4f86(hint:\u8f49\u6210<code>rune<\/code>)\u770b\u770b\u600e\u9ebc\u56de\u4e8b\u4e86\u3002\u4e0d\u904e\u53ef\u4ee5\u5148\u8aaa\u7d50\u8ad6\uff0c\u5c31\u662f\u751f\u6210\u4e86\u67d0\u500b\u6e2c\u8cc7\u975eascii\u5b57\u4e32\uff0c\u53cd\u8f49\u5f8c\u5c31\u5f97\u5230\u4e00\u500b\u975eUTF-8\u5b57\u4e32(\u7406\u8ad6\u4e0aascii\u8ddfUTF-8\uff0c\u5f8c\u8005\u61c9\u8a72\u8981\u5b8c\u7f8e\u5305\u542b\u524d\u8005\uff09\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u5c31\u662ffuzz\u8981\u505a\u7684\u4e8b\u60c5\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u5347\u7d1a\u8981\u907f\u514d\u7684\u96f7<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u5b89\u88ddbinary\u4e0d\u80fd\u518d\u7528<code>go get -u<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u9084\u6709\u5f37\u5236 @latest\uff0c\u7528<code>go get -u<\/code>\u50c5\u6703\u5b89\u88ddpackage source\u800c\u4e0d\u6703\u5b89\u88ddbinary<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u5982\u679c\u4f7f\u7528RC\u7248\u672c\uff0c\u5f88\u53ef\u80fd\u6b63\u5f0f\u5305\u7684\u6771\u897f\u6703\u88ab\u79fb\u5230X Package\uff08\u53cd\u4e4b\u4ea6\u7136\uff09<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u5011\u78b0\u5230\u7684\u5c31\u6709slices\u5305\u5f9eRC\u76f4\u63a5\u88ab\u79fb\u5230X Package\u7684\u5305\u4ee5\u81f3\u65bc\u7de8\u8b6f\u70b8\u6389\uff08\u96d6\u7136\u9084\u6eff\u597d\u4fee\u7684\uff09<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u5982\u679c\u6c92\u6307\u5b9a\u7248\u672c\u7684\u8a71\uff0cCICD\u53ef\u80fd\u6703\u56e0\u70ba\u9019\u539f\u56e0\u5931\u6557<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e4b\u524d\u78b0\u904e\u7684\u554f\u984c\uff0c\u6c92\u6307\u5b9a\u7248\u672c\u4e4b\u524d\u6703\u9ed8\u8a8d <code>@latest<\/code>\uff0c\u4f46\u662f\u73fe\u5728\u6c92\u6307\u5b9a\u7248\u672c\u7684\u8a71\u6709\u6642\u5019\u6703\u6293\u5230\u5f88\u5947\u602a\u7684\u7248\u672c&#8230; \u597d\u50cf\u8ddfrelease tag\u8207\u5426\u6709\u95dc\uff0c\u4f46\u662f\u6211\u4e0d\u592a\u78ba\u5b9a\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Build Tag\u8a9e\u6cd5\u7684\u66f4\u6539<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u9019\u500b\u5012\u662f\u9084\u597d\uff0c\u5c31\u662f\u628a\u820a\u7684<code>\/\/ +build &lt;tag&gt;<\/code> annotation\u6539\u6210go\u6a19\u6e96annotation <code>\/\/go:build &lt;tag&gt;<\/code>\u800c\u5df2\u3002\u76ee\u524d\u76f4\u52301.19\u90fd\u9084\u76f8\u5bb9\u820a\u7684tag\u5beb\u6cd5\uff0c\u4e0d\u904e\u5feb\u9ede\u628a\u820a\u5beb\u6cd5\u8f49\u63db\u6210\u65b0\u7684\u5427\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u932f\u8aa4\u7684\u7a2e\u985e \u5728\u8b1b\u9019\u500b\u4e4b\u524d\uff0c\u5148\u63d0\u4e00\u4e0b\u4e3b\u6d41\u8a9e\u8a00\u901a\u5e38\u300c\u932f\u8aa4\u6aa2\u51fa\u300d\u65b9\u9762\u901a\u5e38\u5206\u70ba\u4e09\u500b\u968e\u6bb5\uff1a \u7de8\u8b6f\u524d\u968e\u6bb5 (pre-compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u4e0d\u9700\u8981\u88ab\u7de8\u8b6f\u5373\u53ef\u88ab\u6aa2\u51fa \u5f88\u591a\u8a9e\u8a00\u6c92\u6709\u9019\u6771\u897f\uff0c\u4ed6\u9700\u8981language server protocol(LSP)\u652f\u63f4\uff0c\u5982gopls \u5f88\u591aIDE\u5404\u8a9e\u8a00\u7684\u8ce3\u9ede\u5c31\u662f\u81ea\u5df1\u7368\u5230\u7684LSP\uff0c\u4f46\u662f\u525b\u597d\u62ff\u4f86\u505a\u5229\u5b50\u7684C++\u64c1\u6709\u975e\u5e38\u6df7\u4e82\u7684LSP\u5be6\u4f5c\uff0c\u5e38\u5e38pre-compile time\u5831\u932f\uff0c\u4f46\u662fcompile\u4e0b\u53bb\u6c92\u554f\u984c\uff0c\u4ee5\u53ca\u53cd\u4e4b&#8230;.\u4e3b\u8981\u4e5f\u662f\u56e0\u70baC++\u5be6\u5728\u662f\u904e\u65bc\u8907\u96dc\u3002 \u7de8\u8b6f\u968e\u6bb5 (compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u5728\u7de8\u8b6f\u7684\u6642\u5019\u5c31\u53ef\u4ee5\u627e\u51fa\u4f86 \u524d\u5169\u8005\u4e5f\u53ef\u4ee5\u4e26\u7a31\u70bacompile time\uff0c\u5982\u679c\u6c92\u6709\u8981\u7279\u5225\u6307\u540dLSP\u63d0\u4f9b\u7684\u529f\u80fd\u7684\u8a71\u3002 \u57f7\u884c\u968e\u6bb5 (runtime) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u9700\u8981\u5728\u57f7\u884c\u671f\u624d\u6703\u767c\u4f5c \u800cgo\u662f\u4e00\u500b\u6eff\u7279\u6b8a\u7684\u8a9e\u8a00\uff0c\u4ed6\u80fd\u5920\u628a\u4e00\u4e9bruntime\u624d\u80fd\u6aa2\u51fa\u7684\u6771\u897f\u85c9\u7531gopls\u4ee5\u53cago vet \u505a\u7d50\u69cb\u6027\u8a9e\u6cd5\u6aa2\u67e5\u4e0b\uff0c\u5c07\u932f\u8aa4\u628aruntime\u63d0\u524d\u5230pre-compile time\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"aside","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[38,84],"tags":[169,86],"class_list":["post-1146","post","type-post","status-publish","format-aside","hentry","category-code","category-84","tag-generic","tag-golang","post_format-post-format-aside"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Go 1.18:Generic and Fuzz - Fox Nest<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.rayer.idv.tw\/blog\/?p=1146\" \/>\n<meta property=\"og:locale\" content=\"zh_TW\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Go 1.18:Generic and Fuzz - Fox Nest\" \/>\n<meta property=\"og:description\" content=\"\u932f\u8aa4\u7684\u7a2e\u985e \u5728\u8b1b\u9019\u500b\u4e4b\u524d\uff0c\u5148\u63d0\u4e00\u4e0b\u4e3b\u6d41\u8a9e\u8a00\u901a\u5e38\u300c\u932f\u8aa4\u6aa2\u51fa\u300d\u65b9\u9762\u901a\u5e38\u5206\u70ba\u4e09\u500b\u968e\u6bb5\uff1a \u7de8\u8b6f\u524d\u968e\u6bb5 (pre-compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u4e0d\u9700\u8981\u88ab\u7de8\u8b6f\u5373\u53ef\u88ab\u6aa2\u51fa \u5f88\u591a\u8a9e\u8a00\u6c92\u6709\u9019\u6771\u897f\uff0c\u4ed6\u9700\u8981language server protocol(LSP)\u652f\u63f4\uff0c\u5982gopls \u5f88\u591aIDE\u5404\u8a9e\u8a00\u7684\u8ce3\u9ede\u5c31\u662f\u81ea\u5df1\u7368\u5230\u7684LSP\uff0c\u4f46\u662f\u525b\u597d\u62ff\u4f86\u505a\u5229\u5b50\u7684C++\u64c1\u6709\u975e\u5e38\u6df7\u4e82\u7684LSP\u5be6\u4f5c\uff0c\u5e38\u5e38pre-compile time\u5831\u932f\uff0c\u4f46\u662fcompile\u4e0b\u53bb\u6c92\u554f\u984c\uff0c\u4ee5\u53ca\u53cd\u4e4b&#8230;.\u4e3b\u8981\u4e5f\u662f\u56e0\u70baC++\u5be6\u5728\u662f\u904e\u65bc\u8907\u96dc\u3002 \u7de8\u8b6f\u968e\u6bb5 (compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u5728\u7de8\u8b6f\u7684\u6642\u5019\u5c31\u53ef\u4ee5\u627e\u51fa\u4f86 \u524d\u5169\u8005\u4e5f\u53ef\u4ee5\u4e26\u7a31\u70bacompile time\uff0c\u5982\u679c\u6c92\u6709\u8981\u7279\u5225\u6307\u540dLSP\u63d0\u4f9b\u7684\u529f\u80fd\u7684\u8a71\u3002 \u57f7\u884c\u968e\u6bb5 (runtime) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u9700\u8981\u5728\u57f7\u884c\u671f\u624d\u6703\u767c\u4f5c \u800cgo\u662f\u4e00\u500b\u6eff\u7279\u6b8a\u7684\u8a9e\u8a00\uff0c\u4ed6\u80fd\u5920\u628a\u4e00\u4e9bruntime\u624d\u80fd\u6aa2\u51fa\u7684\u6771\u897f\u85c9\u7531gopls\u4ee5\u53cago vet \u505a\u7d50\u69cb\u6027\u8a9e\u6cd5\u6aa2\u67e5\u4e0b\uff0c\u5c07\u932f\u8aa4\u628aruntime\u63d0\u524d\u5230pre-compile time\u3002\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.rayer.idv.tw\/blog\/?p=1146\" \/>\n<meta property=\"og:site_name\" content=\"Fox Nest\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-18T04:01:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-09-04T03:51:10+00:00\" \/>\n<meta name=\"author\" content=\"Rayer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@Rayer\" \/>\n<meta name=\"twitter:site\" content=\"@Rayer\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rayer\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u4f30\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146\"},\"author\":{\"name\":\"Rayer\",\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#\\\/schema\\\/person\\\/498379badb270198fef0edd6b06a5bd7\"},\"headline\":\"Go 1.18:Generic and Fuzz\",\"datePublished\":\"2022-08-18T04:01:22+00:00\",\"dateModified\":\"2022-09-04T03:51:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146\"},\"wordCount\":196,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#\\\/schema\\\/person\\\/498379badb270198fef0edd6b06a5bd7\"},\"keywords\":[\"generic\",\"golang\"],\"articleSection\":[\"\u5beb\u5bebCode\",\"\u6280\u8853\"],\"inLanguage\":\"zh-TW\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146\",\"url\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146\",\"name\":\"Go 1.18:Generic and Fuzz - Fox Nest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#website\"},\"datePublished\":\"2022-08-18T04:01:22+00:00\",\"dateModified\":\"2022-09-04T03:51:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146#breadcrumb\"},\"inLanguage\":\"zh-TW\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?p=1146#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Go 1.18:Generic and Fuzz\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/\",\"name\":\"Fox Nest\",\"description\":\"\u6709\u6642\u5019\u7e3d\u60f3\u6709\u500b\u5730\u65b9\u653e\u653e\u96a8\u624b\u4e82\u5beb\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#\\\/schema\\\/person\\\/498379badb270198fef0edd6b06a5bd7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-TW\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.rayer.idv.tw\\\/blog\\\/#\\\/schema\\\/person\\\/498379badb270198fef0edd6b06a5bd7\",\"name\":\"Rayer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-TW\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/www.rayer.idv.tw\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.rayer.idv.tw\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.rayer.idv.tw\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1\",\"width\":800,\"height\":600,\"caption\":\"Rayer\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/www.rayer.idv.tw\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1\"},\"sameAs\":[\"https:\\\/\\\/www.rayer.idv.tw\",\"https:\\\/\\\/x.com\\\/Rayer\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Go 1.18:Generic and Fuzz - Fox Nest","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146","og_locale":"zh_TW","og_type":"article","og_title":"Go 1.18:Generic and Fuzz - Fox Nest","og_description":"\u932f\u8aa4\u7684\u7a2e\u985e \u5728\u8b1b\u9019\u500b\u4e4b\u524d\uff0c\u5148\u63d0\u4e00\u4e0b\u4e3b\u6d41\u8a9e\u8a00\u901a\u5e38\u300c\u932f\u8aa4\u6aa2\u51fa\u300d\u65b9\u9762\u901a\u5e38\u5206\u70ba\u4e09\u500b\u968e\u6bb5\uff1a \u7de8\u8b6f\u524d\u968e\u6bb5 (pre-compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u4e0d\u9700\u8981\u88ab\u7de8\u8b6f\u5373\u53ef\u88ab\u6aa2\u51fa \u5f88\u591a\u8a9e\u8a00\u6c92\u6709\u9019\u6771\u897f\uff0c\u4ed6\u9700\u8981language server protocol(LSP)\u652f\u63f4\uff0c\u5982gopls \u5f88\u591aIDE\u5404\u8a9e\u8a00\u7684\u8ce3\u9ede\u5c31\u662f\u81ea\u5df1\u7368\u5230\u7684LSP\uff0c\u4f46\u662f\u525b\u597d\u62ff\u4f86\u505a\u5229\u5b50\u7684C++\u64c1\u6709\u975e\u5e38\u6df7\u4e82\u7684LSP\u5be6\u4f5c\uff0c\u5e38\u5e38pre-compile time\u5831\u932f\uff0c\u4f46\u662fcompile\u4e0b\u53bb\u6c92\u554f\u984c\uff0c\u4ee5\u53ca\u53cd\u4e4b&#8230;.\u4e3b\u8981\u4e5f\u662f\u56e0\u70baC++\u5be6\u5728\u662f\u904e\u65bc\u8907\u96dc\u3002 \u7de8\u8b6f\u968e\u6bb5 (compile time) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u5728\u7de8\u8b6f\u7684\u6642\u5019\u5c31\u53ef\u4ee5\u627e\u51fa\u4f86 \u524d\u5169\u8005\u4e5f\u53ef\u4ee5\u4e26\u7a31\u70bacompile time\uff0c\u5982\u679c\u6c92\u6709\u8981\u7279\u5225\u6307\u540dLSP\u63d0\u4f9b\u7684\u529f\u80fd\u7684\u8a71\u3002 \u57f7\u884c\u968e\u6bb5 (runtime) \u6307\u7684\u662f\u9019\u500b\u932f\u8aa4\u9700\u8981\u5728\u57f7\u884c\u671f\u624d\u6703\u767c\u4f5c \u800cgo\u662f\u4e00\u500b\u6eff\u7279\u6b8a\u7684\u8a9e\u8a00\uff0c\u4ed6\u80fd\u5920\u628a\u4e00\u4e9bruntime\u624d\u80fd\u6aa2\u51fa\u7684\u6771\u897f\u85c9\u7531gopls\u4ee5\u53cago vet \u505a\u7d50\u69cb\u6027\u8a9e\u6cd5\u6aa2\u67e5\u4e0b\uff0c\u5c07\u932f\u8aa4\u628aruntime\u63d0\u524d\u5230pre-compile time\u3002","og_url":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146","og_site_name":"Fox Nest","article_published_time":"2022-08-18T04:01:22+00:00","article_modified_time":"2022-09-04T03:51:10+00:00","author":"Rayer","twitter_card":"summary_large_image","twitter_creator":"@Rayer","twitter_site":"@Rayer","twitter_misc":{"\u4f5c\u8005:":"Rayer","\u9810\u4f30\u95b1\u8b80\u6642\u9593":"7 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146#article","isPartOf":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146"},"author":{"name":"Rayer","@id":"https:\/\/www.rayer.idv.tw\/blog\/#\/schema\/person\/498379badb270198fef0edd6b06a5bd7"},"headline":"Go 1.18:Generic and Fuzz","datePublished":"2022-08-18T04:01:22+00:00","dateModified":"2022-09-04T03:51:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146"},"wordCount":196,"commentCount":0,"publisher":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/#\/schema\/person\/498379badb270198fef0edd6b06a5bd7"},"keywords":["generic","golang"],"articleSection":["\u5beb\u5bebCode","\u6280\u8853"],"inLanguage":"zh-TW","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.rayer.idv.tw\/blog\/?p=1146#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146","url":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146","name":"Go 1.18:Generic and Fuzz - Fox Nest","isPartOf":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/#website"},"datePublished":"2022-08-18T04:01:22+00:00","dateModified":"2022-09-04T03:51:10+00:00","breadcrumb":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146#breadcrumb"},"inLanguage":"zh-TW","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.rayer.idv.tw\/blog\/?p=1146"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.rayer.idv.tw\/blog\/?p=1146#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/www.rayer.idv.tw\/blog"},{"@type":"ListItem","position":2,"name":"Go 1.18:Generic and Fuzz"}]},{"@type":"WebSite","@id":"https:\/\/www.rayer.idv.tw\/blog\/#website","url":"https:\/\/www.rayer.idv.tw\/blog\/","name":"Fox Nest","description":"\u6709\u6642\u5019\u7e3d\u60f3\u6709\u500b\u5730\u65b9\u653e\u653e\u96a8\u624b\u4e82\u5beb","publisher":{"@id":"https:\/\/www.rayer.idv.tw\/blog\/#\/schema\/person\/498379badb270198fef0edd6b06a5bd7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.rayer.idv.tw\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-TW"},{"@type":["Person","Organization"],"@id":"https:\/\/www.rayer.idv.tw\/blog\/#\/schema\/person\/498379badb270198fef0edd6b06a5bd7","name":"Rayer","image":{"@type":"ImageObject","inLanguage":"zh-TW","@id":"https:\/\/i0.wp.com\/www.rayer.idv.tw\/blog\/wp-content\/uploads\/2022\/02\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1","url":"https:\/\/i0.wp.com\/www.rayer.idv.tw\/blog\/wp-content\/uploads\/2022\/02\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.rayer.idv.tw\/blog\/wp-content\/uploads\/2022\/02\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1","width":800,"height":600,"caption":"Rayer"},"logo":{"@id":"https:\/\/i0.wp.com\/www.rayer.idv.tw\/blog\/wp-content\/uploads\/2022\/02\/564120_490926324264770_332274456_n.jpg?fit=800%2C600&ssl=1"},"sameAs":["https:\/\/www.rayer.idv.tw","https:\/\/x.com\/Rayer"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pacpZ9-iu","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1146"}],"version-history":[{"count":17,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1146\/revisions"}],"predecessor-version":[{"id":1166,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1146\/revisions\/1166"}],"wp:attachment":[{"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rayer.idv.tw\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}