-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
291eb81
commit 5bd360d
Showing
76 changed files
with
477 additions
and
483 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<!doctype html><html lang=zh dir=auto><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><title>c++ | 自由庄园</title><meta name=keywords content><meta name=description content="In Pursuit of Hubris"><meta name=author content="Ramsay Leung"><link rel=canonical href=https://ramsayleung.github.io/zh/categories/c++/><meta name=google-site-verification content="XYZabc"><meta name=yandex-verification content="XYZabc"><meta name=msvalidate.01 content="XYZabc"><link crossorigin=anonymous href=/assets/css/stylesheet.5cfc680b1eeaeef9efbced92d46c2a9e876b72ee14fba85846afc4cff9e6e6f8.css integrity="sha256-XPxoCx7q7vnvvO2S1Gwqnodrcu4U+6hYRq/Ez/nm5vg=" rel="preload stylesheet" as=style><link rel=icon href=https://ramsayleung.github.io/favicon.ico><link rel=icon type=image/png sizes=16x16 href=https://ramsayleung.github.io/favicon-16x16.png><link rel=icon type=image/png sizes=32x32 href=https://ramsayleung.github.io/favicon-32x32.png><link rel=apple-touch-icon href=https://ramsayleung.github.io/apple-touch-icon.png><link rel=mask-icon href=https://ramsayleung.github.io/%3Clink%20/%20abs%20url%3E><meta name=theme-color content="#2e2e33"><meta name=msapplication-TileColor content="#2e2e33"><link rel=alternate type=application/rss+xml href=https://ramsayleung.github.io/zh/categories/c++/index.xml><link rel=alternate hreflang=zh href=https://ramsayleung.github.io/zh/categories/c++/><noscript><style>#theme-toggle,.top-link{display:none}</style><style>@media(prefers-color-scheme:dark){:root{--theme:rgb(29, 30, 32);--entry:rgb(46, 46, 51);--primary:rgb(218, 218, 219);--secondary:rgb(155, 156, 157);--tertiary:rgb(65, 66, 68);--content:rgb(196, 196, 197);--hljs-bg:rgb(46, 46, 51);--code-bg:rgb(55, 56, 62);--border:rgb(51, 51, 51)}.list{background:var(--theme)}.list:not(.dark)::-webkit-scrollbar-track{background:0 0}.list:not(.dark)::-webkit-scrollbar-thumb{border-color:var(--theme)}}</style></noscript><script async src="https://www.googletagmanager.com/gtag/js?id=G-9MG65HQHEL"></script> | ||
<script>var doNotTrack=!1;if(!doNotTrack){window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","G-9MG65HQHEL",{anonymize_ip:!1})}</script><meta property="og:title" content="c++"><meta property="og:description" content="In Pursuit of Hubris"><meta property="og:type" content="website"><meta property="og:url" content="https://ramsayleung.github.io/zh/categories/c++/"><meta property="og:image" content="https://ramsayleung.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E"><meta property="og:site_name" content="自由庄园"><meta name=twitter:card content="summary_large_image"><meta name=twitter:image content="https://ramsayleung.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E"><meta name=twitter:title content="c++"><meta name=twitter:description content="In Pursuit of Hubris"></head><body class=list id=top><script>localStorage.getItem("pref-theme")==="dark"?document.body.classList.add("dark"):localStorage.getItem("pref-theme")==="light"?document.body.classList.remove("dark"):window.matchMedia("(prefers-color-scheme: dark)").matches&&document.body.classList.add("dark")</script><header class=header><nav class=nav><div class=logo><a href=https://ramsayleung.github.io/zh/ accesskey=h title="Home (Alt + H)"><img src=https://ramsayleung.github.io/apple-touch-icon.png alt aria-label=logo height=35>Home</a><div class=logo-switches><button id=theme-toggle accesskey=t title="(Alt + T)"><svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24" fill="none" stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg><svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24" fill="none" stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></button><ul class=lang-switch><li>|</li><li><a href=https://ramsayleung.github.io/en/ title=English aria-label=English>En</a></li></ul></div></div><ul id=menu><li><a href=https://ramsayleung.github.io/zh/archives/ title=归档><span>归档</span></a></li><li><a href=https://ramsayleung.github.io/zh/search/ title=搜索><span>搜索</span></a></li><li><a href=https://ramsayleung.github.io/zh/categories/ title=目录><span>目录</span></a></li><li><a href=https://ramsayleung.github.io/zh/tags/ title=标签><span>标签</span></a></li><li><a href=https://ramsayleung.github.io/zh/about_me_zh/ title=关于><span>关于</span></a></li></ul></nav></header><main class=main><header class=page-header><div class=breadcrumbs><a href=https://ramsayleung.github.io/zh/>主页</a></div><h1>c++ | ||
<a href=/zh/categories/c++/index.xml title=RSS aria-label=RSS><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" height="23"><path d="M4 11a9 9 0 019 9"/><path d="M4 4a16 16 0 0116 16"/><circle cx="5" cy="19" r="1"/></svg></a></h1></header><article class="post-entry tag-entry"><header class=entry-header><h2>Rust模拟C++的函数重载</h2></header><div class=entry-content><p>1 函数重载(function overloading) 所谓的函数重载,指的是某些语言支持创建函数名相同,但函数签名不同的多个函数,所谓的函数签名,既指参数类型,也指...</p></div><footer class=entry-footer><span title='2024-08-30 22:23:00 -0700 -0700'>八月 30, 2024</span> · 2 分钟 · 861 字 · Ramsay Leung</footer><a class=entry-link aria-label="post link to Rust模拟C++的函数重载" href=https://ramsayleung.github.io/zh/post/2024/rust%E6%A8%A1%E6%8B%9Fc++%E7%9A%84%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD/></a></article></main><footer class=footer><span>See this site’s source code <a href=https://github.com/ramsayleung/ramsayleung.github.io>here</a>, licensed under GPLv3 ·</span> | ||
<span>Powered by | ||
<a href=https://gohugo.io/ rel="noopener noreferrer" target=_blank>Hugo</a> & | ||
<a href=https://github.com/adityatelange/hugo-PaperMod/ rel=noopener target=_blank>PaperMod</a></span></footer><a href=#top aria-label="go to top" title="Go to Top (Alt + G)" class=top-link id=top-link accesskey=g><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentcolor"><path d="M12 6H0l6-6z"/></svg></a><script>let menu=document.getElementById("menu");menu&&(menu.scrollLeft=localStorage.getItem("menu-scroll-position"),menu.onscroll=function(){localStorage.setItem("menu-scroll-position",menu.scrollLeft)}),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){e.preventDefault();var t=this.getAttribute("href").substr(1);window.matchMedia("(prefers-reduced-motion: reduce)").matches?document.querySelector(`[id='${decodeURIComponent(t)}']`).scrollIntoView():document.querySelector(`[id='${decodeURIComponent(t)}']`).scrollIntoView({behavior:"smooth"}),t==="top"?history.replaceState(null,null," "):history.pushState(null,null,`#${t}`)})})</script><script>var mybutton=document.getElementById("top-link");window.onscroll=function(){document.body.scrollTop>800||document.documentElement.scrollTop>800?(mybutton.style.visibility="visible",mybutton.style.opacity="1"):(mybutton.style.visibility="hidden",mybutton.style.opacity="0")}</script><script>document.getElementById("theme-toggle").addEventListener("click",()=>{document.body.className.includes("dark")?(document.body.classList.remove("dark"),localStorage.setItem("pref-theme","light")):(document.body.classList.add("dark"),localStorage.setItem("pref-theme","dark"))})</script></body></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?xml version="1.0" encoding="utf-8" standalone="yes"?> | ||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"> | ||
<channel> | ||
<title>c++ on 自由庄园</title> | ||
<link>https://ramsayleung.github.io/zh/categories/c++/</link> | ||
<description>Recent content in c++ on 自由庄园</description> | ||
<image> | ||
<title>自由庄园</title> | ||
<url>https://ramsayleung.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url> | ||
<link>https://ramsayleung.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link> | ||
</image> | ||
<generator>Hugo -- gohugo.io</generator> | ||
<language>en-us</language> | ||
<copyright>See this site's source code [here](https://github.com/ramsayleung/ramsayleung.github.io), licensed under GPLv3 ·</copyright> | ||
<lastBuildDate>Fri, 30 Aug 2024 22:23:00 -0700</lastBuildDate><atom:link href="https://ramsayleung.github.io/zh/categories/c++/index.xml" rel="self" type="application/rss+xml" /> | ||
<item> | ||
<title>Rust模拟C++的函数重载</title> | ||
<link>https://ramsayleung.github.io/zh/post/2024/rust%E6%A8%A1%E6%8B%9Fc++%E7%9A%84%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD/</link> | ||
<pubDate>Fri, 30 Aug 2024 22:23:00 -0700</pubDate> | ||
|
||
<guid>https://ramsayleung.github.io/zh/post/2024/rust%E6%A8%A1%E6%8B%9Fc++%E7%9A%84%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD/</guid> | ||
<description>1 函数重载(function overloading) 所谓的函数重载,指的是某些语言支持创建函数名相同,但函数签名不同的多个函数,所谓的函数签名,既指参数类型,也指</description> | ||
<content:encoded><![CDATA[<h2 id="函数重载--function-overloading"><!-- raw HTML omitted -->1<!-- raw HTML omitted --> 函数重载(function overloading)</h2> | ||
<p>所谓的函数重载,指的是某些语言支持创建函数名相同,但函数签名不同的多个函数,所谓的函数签名,既指参数类型,也指参数的数量。 <!-- raw HTML omitted --></p> | ||
<p>如C++,Java都是支持函数重载的,而Rust是不支持函数重载的, 个人猜测可能是Rust最初的设计者认为函数重载可能会导致增加代码理解难度,尤其是在C++里面,隐式类型转换叠加函数重载,可能看代码都看不出实际调用的是哪个版本的函数。 <!-- raw HTML omitted --></p> | ||
<h2 id="rust版本的函数重载"><!-- raw HTML omitted -->2<!-- raw HTML omitted --> Rust版本的函数重载</h2> | ||
<p>但是我个人觉得函数重载在大部分情况下都是很方便,也不需要为相同的函数想不同的名字,毕竟命名是编程最难的问题之一。 <!-- raw HTML omitted --> | ||
今天重读 Programming Rust, 2nd Edition关于 <code>Into</code> 这个trait 的功能的时候,突然意识到,可以使用 <code>Into</code> 模拟出部分的函数重载功能。 <!-- raw HTML omitted --></p> | ||
<p>为什么说是「部分」呢,因为前文提到,所谓的函数重载是指多个同名但函数签名不一样的函数,而Rust能模拟的就是参数类型不一样,但是参数数量一致的重载函数。 <!-- raw HTML omitted --></p> | ||
<p>假设我们想实现自己的 <code>ping</code> 命名, 入参可以是 <a href="https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html"><code>Ipv4Addr</code></a> 这个 struct, ipv4的地址也可以使用2进制来表示, 又或者可以使用 u32 来表示,毕竟只有32位。 <!-- raw HTML omitted --></p> | ||
<p>如果用 C++, 我们可以写3个重载函数,入参分别是, <code>Ipv4Addr</code>, <code>bitset</code> 和 <code>uint32</code>. 在 Rust, 我们也实现类似的函数: <!-- raw HTML omitted --></p> | ||
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">net</span>::<span class="n">Ipv4Addr</span><span class="p">;</span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">ping</span><span class="o"><</span><span class="n">A</span><span class="o">></span><span class="p">(</span><span class="n">address</span>: <span class="nc">A</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">std</span>::<span class="n">io</span>::<span class="nb">Result</span><span class="o"><</span><span class="kt">bool</span><span class="o">></span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w"> </span><span class="n">A</span>: <span class="nb">Into</span><span class="o"><</span><span class="n">Ipv4Addr</span><span class="o">></span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">{</span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">ipv4_address</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">address</span><span class="p">.</span><span class="n">into</span><span class="p">();</span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> | ||
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> | ||
</span></span></span></code></pre></div><p>需要注意的是,上面函数的入参并不是 <code>Ipv4Addr</code>, 而是 <code>Into<Ipv4Addr>=,这就是意味着,所有实现了 =Into<Ipv4Addr></code> 这个 trait 的类型都可以是 <code>ping</code> 的入参,而恰好 <code>u32</code> 和 <code>[u8; 4]</code> 都实现了 =Into<Ipv4Addr>=,所以下面的调用都是编译通过的: <!-- raw HTML omitted --></p> | ||
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">ping</span><span class="p">(</span><span class="n">Ipv4Addr</span>::<span class="n">new</span><span class="p">(</span><span class="mi">23</span><span class="p">,</span><span class="w"> </span><span class="mi">21</span><span class="p">,</span><span class="w"> </span><span class="mi">68</span><span class="p">,</span><span class="w"> </span><span class="mi">141</span><span class="p">)));</span><span class="w"> </span><span class="c1">// pass an Ipv4Addr | ||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">ping</span><span class="p">([</span><span class="mi">66</span><span class="p">,</span><span class="w"> </span><span class="mi">146</span><span class="p">,</span><span class="w"> </span><span class="mi">219</span><span class="p">,</span><span class="w"> </span><span class="mi">98</span><span class="p">]));</span><span class="w"> </span><span class="c1">// pass a [u8; 4] | ||
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">ping</span><span class="p">(</span><span class="mh">0xd076eb94_</span><span class="k">u32</span><span class="p">));</span><span class="w"> </span><span class="c1">// pass a u32 | ||
</span></span></span></code></pre></div><p>当然,如果你实现了 <code>impl From<u32> for Ipv4Addr</code>, Rust 编译器也会贴心地帮你把反向的 <code>Into<Ipv4Addr></code> 也实现掉。 <!-- raw HTML omitted --></p> | ||
<h2 id="限制"><!-- raw HTML omitted -->3<!-- raw HTML omitted --> 限制</h2> | ||
<p>看完上面的函数实现,有经验的朋友可能就会发现了,Rust版本的函数重载限制比C++的要多。 <!-- raw HTML omitted --></p> | ||
<p>在C++版本的函数重载中: <!-- raw HTML omitted --></p> | ||
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">func1</span><span class="p">(</span><span class="n">Type1</span> <span class="n">foo</span><span class="p">);</span> | ||
</span></span><span class="line"><span class="cl"> | ||
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">func1</span><span class="p">(</span><span class="n">Type2</span> <span class="n">bar</span><span class="p">);</span> | ||
</span></span></code></pre></div><p>参数类型 <code>Type1</code> 和 <code>Type2</code> 并不需要存在任何关系,但是在 Rust 版本中,需要两个类型之间支持相互转换,所以可以理解成 Rust 的「函数重载」本质就是通过显示类型转换来实现的。 <!-- raw HTML omitted --></p> | ||
<p>毕竟 Rust 设计初衷之一就是支持强类型,就函数重载而言,终归聊胜于无啦。 <!-- raw HTML omitted --></p> | ||
]]></content:encoded> | ||
</item> | ||
|
||
</channel> | ||
</rss> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!doctype html><html lang=en-us><head><title>https://ramsayleung.github.io/zh/categories/c++/</title><link rel=canonical href=https://ramsayleung.github.io/zh/categories/c++/><meta name=robots content="noindex"><meta charset=utf-8><meta http-equiv=refresh content="0; url=https://ramsayleung.github.io/zh/categories/c++/"></head></html> |
Oops, something went wrong.