Merge 8d983909d79504d8eb43f7aaa8460acc4a20c6ef into 461f6955d69bb468b92d9c9abeec55a3befac123
This commit is contained in:
commit
5ae17842f2
@ -5,6 +5,36 @@ package main
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
type MyInt16 int16
|
||||||
|
type MyInt int
|
||||||
|
|
||||||
|
func (m MyInt16) String() string {
|
||||||
|
return fmt.Sprintf("{MyInt16: %d}", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MyInt) String() string {
|
||||||
|
return fmt.Sprintf("{MyInt: %d}", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// `~` the underlying type of T must be itself, and T cannot be an interface.
|
||||||
|
type Number interface {
|
||||||
|
int | ~int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// An interface representing all types with underlying type int that implement the String method.
|
||||||
|
type IntString interface {
|
||||||
|
~int16
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func SumNumber[T Number](a, b T) T {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
func SumIntString[T IntString](a, b T) (T, string) {
|
||||||
|
return a + b, a.String() + ", " + b.String()
|
||||||
|
}
|
||||||
|
|
||||||
// As an example of a generic function, `MapKeys` takes
|
// As an example of a generic function, `MapKeys` takes
|
||||||
// a map of any type and returns a slice of its keys.
|
// a map of any type and returns a slice of its keys.
|
||||||
// This function has two type parameters - `K` and `V`;
|
// This function has two type parameters - `K` and `V`;
|
||||||
@ -71,4 +101,13 @@ func main() {
|
|||||||
lst.Push(13)
|
lst.Push(13)
|
||||||
lst.Push(23)
|
lst.Push(23)
|
||||||
fmt.Println("list:", lst.GetAll())
|
fmt.Println("list:", lst.GetAll())
|
||||||
|
|
||||||
|
// We can use `MyInt16` as the parameter of the function `SumNumber`, because its underlying type is int16.
|
||||||
|
fmt.Println(SumNumber(MyInt16(1), MyInt16(2)))
|
||||||
|
fmt.Println(SumNumber(1, 2))
|
||||||
|
|
||||||
|
// We can't use `MyInt` as the parameter of the function `SumInString`, because underlying type of `MyInt` is int not int16.
|
||||||
|
// also int16 does not implement `IntString` (missing method String).
|
||||||
|
result, str := SumIntString(MyInt16(1), MyInt16(2))
|
||||||
|
fmt.Printf("result: %d, output: %s\n", result, str)
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
91465956a90881ec8b4cca3968b9aa1f6d9f1447
|
58327cbd52a273bbf23034c16cc679e7dbffdd77
|
||||||
uXlb-AyeYmQ
|
hw05lSyEz41
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
$ go run generics.go
|
$ go run generics.go
|
||||||
keys: [4 1 2]
|
keys: [4 1 2]
|
||||||
list: [10 13 23]
|
list: [10 13 23]
|
||||||
|
{MyInt16: 3}
|
||||||
|
3
|
||||||
|
result: 3, output: {MyInt16: 1}, {MyInt16: 2}
|
||||||
|
124
public/generics
generated
124
public/generics
generated
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td class="code leading">
|
<td class="code leading">
|
||||||
<a href="https://go.dev/play/p/uXlb-AyeYmQ"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
|
<a href="https://go.dev/play/p/hw05lSyEz41"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
|
||||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span></span></span></code></pre>
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span></span></span></code></pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -57,6 +57,92 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">MyInt16</span> <span class="kt">int16</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">MyInt</span> <span class="kt">int</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">m</span> <span class="nx">MyInt16</span><span class="p">)</span> <span class="nf">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"{MyInt16: %d}"</span><span class="p">,</span> <span class="nx">m</span><span class="p">)</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">m</span> <span class="nx">MyInt</span><span class="p">)</span> <span class="nf">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"{MyInt: %d}"</span><span class="p">,</span> <span class="nx">m</span><span class="p">)</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
<p><code>~</code> the underlying type of T must be itself, and T cannot be an interface.</p>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">Number</span> <span class="kd">interface</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="p">|</span> <span class="err">~</span><span class="kt">int16</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
<p>An interface representing all types with underlying type int that implement the String method.</p>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">IntString</span> <span class="kd">interface</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="err">~</span><span class="kt">int16</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="nf">String</span><span class="p">()</span> <span class="kt">string</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nx">SumNumber</span><span class="p">[</span><span class="nx">T</span> <span class="nx">Number</span><span class="p">](</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="nx">T</span><span class="p">)</span> <span class="nx">T</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nx">SumIntString</span><span class="p">[</span><span class="nx">T</span> <span class="nx">IntString</span><span class="p">](</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="nx">T</span><span class="p">)</span> <span class="p">(</span><span class="nx">T</span><span class="p">,</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">.</span><span class="nf">String</span><span class="p">()</span> <span class="o">+</span> <span class="s">", "</span> <span class="o">+</span> <span class="nx">b</span><span class="p">.</span><span class="nf">String</span><span class="p">()</span>
|
||||||
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="docs">
|
<td class="docs">
|
||||||
<p>As an example of a generic function, <code>MapKeys</code> takes
|
<p>As an example of a generic function, <code>MapKeys</code> takes
|
||||||
@ -186,13 +272,38 @@ automatically.</p>
|
|||||||
<td class="docs">
|
<td class="docs">
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td class="code">
|
<td class="code leading">
|
||||||
|
|
||||||
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">lst</span> <span class="o">:=</span> <span class="nx">List</span><span class="p">[</span><span class="kt">int</span><span class="p">]{}</span>
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">lst</span> <span class="o">:=</span> <span class="nx">List</span><span class="p">[</span><span class="kt">int</span><span class="p">]{}</span>
|
||||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span>
|
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span>
|
||||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
||||||
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"list:"</span><span class="p">,</span> <span class="nx">lst</span><span class="p">.</span><span class="nf">GetAll</span><span class="p">())</span>
|
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"list:"</span><span class="p">,</span> <span class="nx">lst</span><span class="p">.</span><span class="nf">GetAll</span><span class="p">())</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
<p>We can use <code>MyInt16</code> as the parameter of the function <code>SumNumber</code>, because its underlying type is int16.</p>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code leading">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nf">SumNumber</span><span class="p">(</span><span class="nf">MyInt16</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nf">MyInt16</span><span class="p">(</span><span class="mi">2</span><span class="p">)))</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nf">SumNumber</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span></span></span></code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="docs">
|
||||||
|
<p>We can’t use <code>MyInt</code> as the parameter of the function <code>SumInString</code>, because underlying type of <code>MyInt</code> is int not int16.
|
||||||
|
also int16 does not implement <code>IntString</code> (missing method String).</p>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td class="code">
|
||||||
|
|
||||||
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">result</span><span class="p">,</span> <span class="nx">str</span> <span class="o">:=</span> <span class="nf">SumIntString</span><span class="p">(</span><span class="nf">MyInt16</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nf">MyInt16</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
|
||||||
|
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"result: %d, output: %s\n"</span><span class="p">,</span> <span class="nx">result</span><span class="p">,</span> <span class="nx">str</span><span class="p">)</span>
|
||||||
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -209,7 +320,10 @@ automatically.</p>
|
|||||||
|
|
||||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="gp">$</span> go run generics.go
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="gp">$</span> go run generics.go
|
||||||
</span></span><span class="line"><span class="cl"><span class="go">keys: [4 1 2]
|
</span></span><span class="line"><span class="cl"><span class="go">keys: [4 1 2]
|
||||||
</span></span></span><span class="line"><span class="cl"><span class="go">list: [10 13 23]</span></span></span></code></pre>
|
</span></span></span><span class="line"><span class="cl"><span class="go">list: [10 13 23]
|
||||||
|
</span></span></span><span class="line"><span class="cl"><span class="go">{MyInt16: 3}
|
||||||
|
</span></span></span><span class="line"><span class="cl"><span class="go">3
|
||||||
|
</span></span></span><span class="line"><span class="cl"><span class="go">result: 3, output: {MyInt16: 1}, {MyInt16: 2}</span></span></span></code></pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -228,7 +342,7 @@ automatically.</p>
|
|||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
var codeLines = [];
|
var codeLines = [];
|
||||||
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func MapKeys[K comparable, V any](m map[K]V) []K {\u000A r :\u003D make([]K, 0, len(m))\u000A for k :\u003D range m {\u000A r \u003D append(r, k)\u000A }\u000A return r\u000A}\u000A');codeLines.push('type List[T any] struct {\u000A head, tail *element[T]\u000A}\u000A');codeLines.push('type element[T any] struct {\u000A next *element[T]\u000A val T\u000A}\u000A');codeLines.push('func (lst *List[T]) Push(v T) {\u000A if lst.tail \u003D\u003D nil {\u000A lst.head \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.head\u000A } else {\u000A lst.tail.next \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.tail.next\u000A }\u000A}\u000A');codeLines.push('func (lst *List[T]) GetAll() []T {\u000A var elems []T\u000A for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A elems \u003D append(elems, e.val)\u000A }\u000A return elems\u000A}\u000A');codeLines.push('func main() {\u000A var m \u003D map[int]string{1: \"2\", 2: \"4\", 4: \"8\"}\u000A');codeLines.push(' fmt.Println(\"keys:\", MapKeys(m))\u000A');codeLines.push(' _ \u003D MapKeys[int, string](m)\u000A');codeLines.push(' lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A fmt.Println(\"list:\", lst.GetAll())\u000A}\u000A');codeLines.push('');
|
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('type MyInt16 int16\u000Atype MyInt int\u000A');codeLines.push('func (m MyInt16) String() string {\u000A return fmt.Sprintf(\"{MyInt16: %d}\", m)\u000A}\u000A');codeLines.push('func (m MyInt) String() string {\u000A return fmt.Sprintf(\"{MyInt: %d}\", m)\u000A}\u000A');codeLines.push('type Number interface {\u000A int | ~int16\u000A}\u000A');codeLines.push('type IntString interface {\u000A ~int16\u000A String() string\u000A}\u000A');codeLines.push('func SumNumber[T Number](a, b T) T {\u000A return a + b\u000A}\u000A');codeLines.push('func SumIntString[T IntString](a, b T) (T, string) {\u000A return a + b, a.String() + \", \" + b.String()\u000A}\u000A');codeLines.push('func MapKeys[K comparable, V any](m map[K]V) []K {\u000A r :\u003D make([]K, 0, len(m))\u000A for k :\u003D range m {\u000A r \u003D append(r, k)\u000A }\u000A return r\u000A}\u000A');codeLines.push('type List[T any] struct {\u000A head, tail *element[T]\u000A}\u000A');codeLines.push('type element[T any] struct {\u000A next *element[T]\u000A val T\u000A}\u000A');codeLines.push('func (lst *List[T]) Push(v T) {\u000A if lst.tail \u003D\u003D nil {\u000A lst.head \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.head\u000A } else {\u000A lst.tail.next \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.tail.next\u000A }\u000A}\u000A');codeLines.push('func (lst *List[T]) GetAll() []T {\u000A var elems []T\u000A for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A elems \u003D append(elems, e.val)\u000A }\u000A return elems\u000A}\u000A');codeLines.push('func main() {\u000A var m \u003D map[int]string{1: \"2\", 2: \"4\", 4: \"8\"}\u000A');codeLines.push(' fmt.Println(\"keys:\", MapKeys(m))\u000A');codeLines.push(' _ \u003D MapKeys[int, string](m)\u000A');codeLines.push(' lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A fmt.Println(\"list:\", lst.GetAll())\u000A');codeLines.push(' fmt.Println(SumNumber(MyInt16(1), MyInt16(2)))\u000A fmt.Println(SumNumber(1, 2))\u000A');codeLines.push(' result, str :\u003D SumIntString(MyInt16(1), MyInt16(2))\u000A fmt.Printf(\"result: %d, output: %s\\n\", result, str)\u000A}\u000A');codeLines.push('');
|
||||||
</script>
|
</script>
|
||||||
<script src="site.js" async></script>
|
<script src="site.js" async></script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user