mirror of
https://github.com/jaywcjlove/reference.git
synced 2025-06-16 20:21:22 +08:00
Merge branch 'jaywcjlove:main' into feat/threejs
This commit is contained in:
@ -337,6 +337,7 @@ jobs:
|
||||
<a href="https://github.com/LesterChang0987" title="Steve Hartwell"><img src="https://avatars.githubusercontent.com/u/114913921?v=4" width="42;" alt="Steve Hartwell"/></a>
|
||||
<a href="https://github.com/nangongchengfeng" title="南宫乘风"><img src="https://avatars.githubusercontent.com/u/46562911?v=4" width="42;" alt="南宫乘风"/></a>
|
||||
<a href="https://github.com/aixcyi" title="砹小翼"><img src="https://avatars.githubusercontent.com/u/75880483?v=4" width="42;" alt="砹小翼"/></a>
|
||||
<a href="https://github.com/h7ml" title="h7ml"><img src="https://avatars.githubusercontent.com/u/55233292?v=4" width="42;" alt="h7ml"/></a>
|
||||
<a href="https://github.com/Alex20180512" title="Alex"><img src="https://avatars.githubusercontent.com/u/115539090?v=4" width="42;" alt="Alex"/></a>
|
||||
<a href="https://github.com/LufsX" title="LufsX"><img src="https://avatars.githubusercontent.com/u/33221883?v=4" width="42;" alt="LufsX"/></a>
|
||||
<a href="https://github.com/mailbaoer" title="baoer"><img src="https://avatars.githubusercontent.com/u/5282978?v=4" width="42;" alt="baoer"/></a>
|
||||
@ -349,7 +350,6 @@ jobs:
|
||||
<a href="https://github.com/qyl27" title="秋 雨落"><img src="https://avatars.githubusercontent.com/u/53731501?v=4" width="42;" alt="秋 雨落"/></a>
|
||||
<a href="https://github.com/MackDing" title="Blossom"><img src="https://avatars.githubusercontent.com/u/19878893?v=4" width="42;" alt="Blossom"/></a>
|
||||
<a href="https://github.com/1250422131" title="萌新杰少"><img src="https://avatars.githubusercontent.com/u/52126790?v=4" width="42;" alt="萌新杰少"/></a>
|
||||
<a href="https://github.com/h7ml" title="h7ml"><img src="https://avatars.githubusercontent.com/u/55233292?v=4" width="42;" alt="h7ml"/></a>
|
||||
<a href="https://github.com/chaos-cn" title="chaos"><img src="https://avatars.githubusercontent.com/u/71205599?v=4" width="42;" alt="chaos"/></a>
|
||||
<a href="https://github.com/xia0ne" title="YuRuiH"><img src="https://avatars.githubusercontent.com/u/32591223?v=4" width="42;" alt="YuRuiH"/></a>
|
||||
<a href="https://github.com/Willxup" title="Willxup"><img src="https://avatars.githubusercontent.com/u/51990395?v=4" width="42;" alt="Willxup"/></a>
|
||||
|
@ -56,6 +56,7 @@ Quick Reference
|
||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153);&class=tag&data-lang=Docker-->
|
||||
[Django](./docs/django.md)<!--rehype:style=background: rgb(12 75 51);&class=contributing tag&data-lang=Python-->
|
||||
[Elixir](./docs/elixir.md)<!--rehype:style=background: rgb(124 26 156);&class=contributing tag&data-lang=Elixir-->
|
||||
[Erlang](./docs/erlang.md)<!--rehype:style=background: rgb(206 55 97);&class=contributing-->
|
||||
[Flask](./docs/flask.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
||||
[FastAPI](./docs/fastapi.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
||||
[Flutter](./docs/flutter.md)<!--rehype:style=background: rgb(150 220 254);&class=contributing tag&data-lang=Dart-->
|
||||
@ -77,7 +78,7 @@ Quick Reference
|
||||
[Scala](./docs/scala.md)<!--rehype:style=background: rgb(34 82 94);-->
|
||||
[Swift](./docs/swift.md)<!--rehype:style=background: rgb(240 81 57);-->
|
||||
[SwiftUI](./docs/swiftui.md)<!--rehype:style=background: rgb(10 127 247);&class=tag&data-lang=swift-->
|
||||
[Spring Boot](./docs/springboot.md)<!--rehype:style=background: rgb(0 255 0);&class=tag&data-lang=Java-->
|
||||
[Spring Boot](./docs/springboot.md)<!--rehype:style=background: rgb(0 149 0);&class=tag&data-lang=Java-->
|
||||
[Lua](./docs/lua.md)<!--rehype:style=background: rgb(3 3 128);-->
|
||||
[Pytorch](./docs/pytorch.md)<!--rehype:style=background: rgb(238 76 44);&class=contributing tag&data-lang=Python&data-info=👆看看还缺点儿什么?-->
|
||||
<!--rehype:class=home-card-->
|
||||
@ -100,6 +101,7 @@ Quick Reference
|
||||
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31);-->
|
||||
[jQuery](./docs/jquery.md)<!--rehype:style=background: rgb(203 183 31);-->
|
||||
[Next.js](./docs/nextjs.md)<!--rehype:style=background: rgb(0 0 0);&class=tag&data-lang=React-->
|
||||
[RxJS](./docs/rxjs.md)<!--rehype:style=background: rgb(151 0 81);-->
|
||||
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173);-->
|
||||
[React Router](./docs/reactrouter.md)<!--rehype:style=background: rgb(244 66 79);&class=tag&data-lang=React-->
|
||||
[React Native](./docs/react-native.md)<!--rehype:style=background: rgb(34 143 173);&class=tag&data-lang=React-->
|
||||
@ -284,6 +286,7 @@ Quick Reference
|
||||
<a href="https://github.com/LesterChang0987" title="Steve Hartwell"><img src="https://avatars.githubusercontent.com/u/114913921?v=4" width="42;" alt="Steve Hartwell"/></a>
|
||||
<a href="https://github.com/nangongchengfeng" title="南宫乘风"><img src="https://avatars.githubusercontent.com/u/46562911?v=4" width="42;" alt="南宫乘风"/></a>
|
||||
<a href="https://github.com/aixcyi" title="砹小翼"><img src="https://avatars.githubusercontent.com/u/75880483?v=4" width="42;" alt="砹小翼"/></a>
|
||||
<a href="https://github.com/h7ml" title="h7ml"><img src="https://avatars.githubusercontent.com/u/55233292?v=4" width="42;" alt="h7ml"/></a>
|
||||
<a href="https://github.com/Alex20180512" title="Alex"><img src="https://avatars.githubusercontent.com/u/115539090?v=4" width="42;" alt="Alex"/></a>
|
||||
<a href="https://github.com/LufsX" title="LufsX"><img src="https://avatars.githubusercontent.com/u/33221883?v=4" width="42;" alt="LufsX"/></a>
|
||||
<a href="https://github.com/mailbaoer" title="baoer"><img src="https://avatars.githubusercontent.com/u/5282978?v=4" width="42;" alt="baoer"/></a>
|
||||
@ -296,7 +299,6 @@ Quick Reference
|
||||
<a href="https://github.com/qyl27" title="秋 雨落"><img src="https://avatars.githubusercontent.com/u/53731501?v=4" width="42;" alt="秋 雨落"/></a>
|
||||
<a href="https://github.com/MackDing" title="Blossom"><img src="https://avatars.githubusercontent.com/u/19878893?v=4" width="42;" alt="Blossom"/></a>
|
||||
<a href="https://github.com/1250422131" title="萌新杰少"><img src="https://avatars.githubusercontent.com/u/52126790?v=4" width="42;" alt="萌新杰少"/></a>
|
||||
<a href="https://github.com/h7ml" title="h7ml"><img src="https://avatars.githubusercontent.com/u/55233292?v=4" width="42;" alt="h7ml"/></a>
|
||||
<a href="https://github.com/chaos-cn" title="chaos"><img src="https://avatars.githubusercontent.com/u/71205599?v=4" width="42;" alt="chaos"/></a>
|
||||
<a href="https://github.com/xia0ne" title="YuRuiH"><img src="https://avatars.githubusercontent.com/u/32591223?v=4" width="42;" alt="YuRuiH"/></a>
|
||||
<a href="https://github.com/Willxup" title="Willxup"><img src="https://avatars.githubusercontent.com/u/51990395?v=4" width="42;" alt="Willxup"/></a>
|
||||
|
12
assets/erlang.svg
Normal file
12
assets/erlang.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 256 225">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#A90533" fill-rule="nonzero" d="M44.3399607 159.659089C25.536634 139.734178 14.5349706 112.207841 14.5628518 79.365069 14.5368716 50.3198413 23.6628914 25.3541383 39.3517627 6.35691059L39.3264162 6.36641554 6.35057459 6.36641554 6.35057459 159.662257 44.3165152 159.662257 44.3399607 159.659089 44.3399607 159.659089ZM218.009347 159.671762C226.109466 150.996277 233.367446 140.779089 239.944238 129.094336L203.445228 110.844831C190.626852 131.684119 171.881188 150.865742 145.959287 150.993742 108.232872 150.865742 93.4102182 118.60594 93.4916246 77.0832472L234.469386 77.0832472C234.657584 72.3954056 234.657584 70.2156037 234.469386 67.9591284 235.389466 43.2557621 228.842456 22.4912472 216.932753 6.32079178L216.871287 6.36704921 248.612753 6.36704921 248.612753 159.662891 217.940278 159.662891 218.009347 159.671762 218.009347 159.671762Z"/>
|
||||
<path fill="#A90533" fill-rule="nonzero" d="M95.7737825,41.4967126 C97.3344954,22.6971878 112.156515,10.0543363 129.535367,10.0163165 C147.032713,10.0543363 159.674931,22.6971878 160.103287,41.4967126 L95.7737825,41.4967126 L95.7737825,41.4967126 Z"/>
|
||||
<polygon fill="currentColor" fill-rule="nonzero" points="26.426 185.668 26.426 179.281 6.807 179.281 6.807 217.149 26.426 217.149 26.426 210.761 14.107 210.761 14.107 200.724 25.969 200.724 25.969 194.337 14.107 194.337 14.107 185.668"/>
|
||||
<path fill="currentColor" fill-rule="nonzero" d="M59.7310102,201.179881 C64.6216241,200.453703 67.3070894,195.607446 67.4870498,190.686416 C67.3070894,182.635723 62.088238,179.304555 54.7123964,179.280475 L44.6751687,179.280475 L44.6751687,217.148198 L51.9749706,217.148198 L51.9749706,202.092356 L61.0997231,217.148198 L70.2244756,217.148198 L59.7310102,201.179881 L59.7310102,201.179881 Z M51.974337,185.212198 L52.8868122,185.212198 C56.8693865,185.361743 59.8583766,186.270416 59.7303766,191.143287 C59.8583766,195.608079 56.9707726,196.819644 52.8868122,196.618139 L51.974337,196.618139 L51.974337,185.212198 L51.974337,185.212198 Z"/>
|
||||
<polygon fill="currentColor" fill-rule="nonzero" points="93.036 179.281 85.737 179.281 85.737 217.149 103.529 217.149 103.529 210.761 93.036 210.761"/>
|
||||
<path fill="currentColor" fill-rule="nonzero" d="M140.940674,209.392158 L144.134337,217.148198 L151.890377,217.148198 L137.74701,178.368 L131.815921,178.368 L116.76008,217.148198 L124.515485,217.148198 L127.709783,209.392158 L140.940674,209.392158 L140.940674,209.392158 Z M139.115723,203.461703 L129.990971,203.461703 L134.097109,189.318337 L139.115723,203.461703 L139.115723,203.461703 Z"/>
|
||||
<polygon fill="currentColor" fill-rule="nonzero" points="165.578 217.149 173.334 217.149 173.334 191.6 193.409 218.061 198.883 218.061 198.883 179.281 191.127 179.281 191.127 204.83 171.052 178.368 165.578 178.368"/>
|
||||
<path fill="currentColor" fill-rule="nonzero" d="M230.820119,197.073743 L230.820119,203.004832 L239.032396,203.004832 C238.861307,207.771248 234.960476,211.809584 230.363882,211.673347 C223.104634,211.809584 219.507327,204.794297 219.414179,198.442455 C219.507327,192.175525 223.053941,184.856713 230.363882,184.755327 C234.20008,184.856079 237.443169,187.480713 239.032396,190.686416 L245.419723,187.492753 C242.610693,181.575604 236.936238,178.294495 230.363882,178.368 C219.051089,178.295129 211.806416,187.632792 211.658139,198.442455 C211.806416,208.982812 218.848951,218.371168 229.907644,218.516911 C241.850931,218.371168 247.373307,208.831366 247.244674,197.986218 L247.244674,197.073743 L230.820119,197.073743 L230.820119,197.073743 L230.820119,197.073743 Z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
27
assets/rxjs.svg
Normal file
27
assets/rxjs.svg
Normal file
@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 255 255">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="11.935%" x2="62.881%" y1="90.18%" y2="37.177%">
|
||||
<stop offset="0%" stop-color="#E01D84"/>
|
||||
<stop offset="40.1%" stop-color="#DF1D85"/>
|
||||
<stop offset="77%" stop-color="#932C87"/>
|
||||
<stop offset="100%" stop-color="#5D2F88"/></linearGradient>
|
||||
<linearGradient id="c" x1="-.146%" x2="99.946%" y1="49.99%" y2="49.99%">
|
||||
<stop offset="0%" stop-color="#E01D84"/>
|
||||
<stop offset="23.8%" stop-color="#DA1E85"/>
|
||||
<stop offset="65.8%" stop-color="#C72085"/>
|
||||
<stop offset="99.9%" stop-color="#B52284"/></linearGradient>
|
||||
<radialGradient id="b" cx="77.558%" cy="33.251%" r="77.293%" fx="77.558%" fy="33.251%" gradientTransform="matrix(.7343 .0024 -.00176 1 .207 -.002)">
|
||||
<stop offset="0%" stop-color="#E01D84"/>
|
||||
<stop offset="13.9%" stop-color="#DE1E85"/>
|
||||
<stop offset="28.5%" stop-color="#D62085"/>
|
||||
<stop offset="43.4%" stop-color="#C92386"/>
|
||||
<stop offset="58.6%" stop-color="#B72786"/>
|
||||
<stop offset="73.9%" stop-color="#9D2B87"/>
|
||||
<stop offset="89.1%" stop-color="#7C2E88"/>
|
||||
<stop offset="100%" stop-color="#5D2F88"/></radialGradient></defs>
|
||||
<g fill="none" transform="translate(1 2)">
|
||||
<path fill="#E32286" d="M14.6140689,158.580855 C9.41406892,142.380855 7.91406892,125.280855 10.9140689,107.680855 C12.2140689,100.380855 14.2140689,93.3808546 16.4140689,86.2808546 C16.4140689,86.2808546 30.2140689,40.9808546 76.9140689,20.2808546 C76.9140689,20.2808546 93.0140689,11.7808546 117.214069,11.1808546 C117.214069,11.1808546 113.914069,7.98085459 111.814069,6.58085459 C100.414069,-1.01914541 83.4140689,-3.51914541 73.1140689,7.18085459 C70.0140689,10.3808546 67.4140689,13.8808546 64.5140689,17.0808546 C61.2140689,20.6808546 57.2140689,23.6808546 52.6140689,25.3808546 C48.6140689,26.8808546 44.6140689,26.5808546 40.5140689,27.2808546 C36.3140689,27.9808546 32.0140689,29.4808546 28.6140689,32.1808546 C24.9140689,35.1808546 23.4140689,39.1808546 23.0140689,43.7808546 C22.6140689,47.3808546 22.7140689,51.0808546 22.5140689,54.6808546 C22.0140689,65.2808546 18.6140689,68.2808546 11.0140689,74.1808546 C7.81406892,76.5808546 5.11406892,79.7808546 3.11406892,83.1808546 C-2.88593108,93.7808546 6.71406892,104.780855 7.21406892,115.480855 C7.31406892,117.680855 7.11406892,119.880855 6.31406892,121.980855 C5.51406892,124.280855 3.91406892,125.780855 2.61406892,127.680855 C0.814068923,130.180855 -0.385931077,133.180855 0.114068923,136.280855 C0.614068923,139.380855 2.21406892,142.280855 3.71406892,144.980855 C6.61406892,149.780855 10.2140689,154.080855 14.0140689,158.180855 C14.2140689,158.180855 14.4140689,158.380855 14.6140689,158.580855"/>
|
||||
<path fill="url(#a)" d="M205.414069,196.980855 C228.414069,186.980855 238.214069,169.680855 238.214069,169.680855 C259.714069,140.380855 252.414069,109.480855 252.414069,109.480855 C238.714069,139.280855 226.214069,147.480855 226.214069,147.480855 C259.914069,96.1808546 226.414069,65.1808546 226.414069,65.1808546 C240.114069,94.3808546 221.914069,129.980855 221.914069,129.980855 C206.614069,162.180855 184.914069,173.680855 184.914069,173.680855 C209.114069,178.180855 226.914069,161.880855 226.914069,161.880855 C192.214069,199.380855 154.614069,197.580855 154.614069,197.580855 C170.414069,215.280855 194.114069,213.780855 194.114069,213.780855 C163.114069,221.080855 134.014069,210.780855 110.114069,190.880855 C105.614069,187.180855 101.314069,183.180855 97.3140689,178.880855 C97.3140689,178.880855 93.7140689,175.080855 93.0140689,174.080855 L92.9140689,173.980855 C92.4140689,192.480855 111.714069,209.680855 111.714069,209.680855 C87.5140689,199.680855 76.4140689,177.980855 76.4140689,177.980855 C76.4140689,177.980855 60.1140689,150.180855 71.9140689,118.480855 C83.7140689,86.7808546 119.414069,79.9808546 119.414069,79.9808546 C148.914069,94.2808546 173.914069,98.7808546 173.914069,98.7808546 C226.614069,107.580855 223.614069,81.7808546 223.614069,81.7808546 C224.114069,59.5808546 190.614069,35.9808546 190.614069,35.9808546 C130.914069,-8.31914541 76.9140689,20.2808546 76.9140689,20.2808546 C30.2140689,40.9808546 16.4140689,86.2808546 16.4140689,86.2808546 C14.2140689,93.3808546 12.2140689,100.380855 10.9140689,107.680855 C5.81406892,137.380855 13.5140689,165.480855 30.2140689,190.480855 C56.2140689,229.280855 98.4140689,242.680855 98.4140689,242.680855 C160.914069,263.880855 203.614069,232.680855 203.614069,232.680855 C242.914069,205.680855 250.814069,174.480855 250.814069,174.480855 C219.114069,199.280855 205.414069,196.980855 205.414069,196.980855 Z M156.614069,51.0808546 C159.614069,51.0808546 162.014069,53.4808546 162.014069,56.4808546 C162.014069,59.4808546 159.614069,61.8808546 156.614069,61.8808546 C153.614069,61.8808546 151.214069,59.4808546 151.214069,56.4808546 C151.214069,53.4808546 153.614069,51.0808546 156.614069,51.0808546 Z"/>
|
||||
<path fill="url(#b)" d="M223.514069,81.6808546 C224.014069,59.4808546 190.514069,35.8808546 190.514069,35.8808546 C130.814069,-8.31914541 76.8140689,20.2808546 76.8140689,20.2808546 C30.1140689,40.9808546 16.3140689,86.2808546 16.3140689,86.2808546 C13.6140689,93.9808546 11.2140689,105.780855 11.2140689,105.780855 C8.31406892,120.580855 9.61406892,134.280855 9.61406892,134.280855 C10.8140689,147.380855 13.7140689,156.180855 13.7140689,156.180855 C16.7140689,165.580855 18.1140689,168.480855 18.1140689,168.480855 C18.0140689,168.180855 17.5140689,165.980855 17.5140689,165.980855 C17.5140689,165.980855 13.3140689,145.780855 17.2140689,126.380855 C17.2140689,126.380855 20.6140689,106.180855 34.4140689,90.5808546 C34.4140689,90.5808546 56.8140689,58.6808546 98.5140689,71.1808546 C98.5140689,71.1808546 107.514069,74.3808546 110.614069,75.9808546 C113.714069,77.4808546 119.114069,79.7808546 119.114069,79.7808546 C148.614069,94.0808546 173.614069,98.5808546 173.614069,98.5808546 C226.514069,107.480855 223.514069,81.6808546 223.514069,81.6808546 L223.514069,81.6808546 Z M156.614069,61.9808546 C153.614069,61.9808546 151.214069,59.5808546 151.214069,56.5808546 C151.214069,53.5808546 153.614069,51.1808546 156.614069,51.1808546 C159.614069,51.1808546 162.014069,53.5808546 162.014069,56.5808546 C162.014069,59.5808546 159.614069,61.9808546 156.614069,61.9808546 Z"/>
|
||||
<path fill="url(#c)" d="M122.414069,41.4808546 L88.3140689,30.8808546 C88.1140689,30.8808546 87.1140689,30.3808546 85.3140689,30.8808546 C85.3140689,30.8808546 65.2140689,35.9808546 68.7140689,46.9808546 C68.7140689,46.9808546 70.8140689,53.8808546 76.5140689,60.5808546 L114.014069,58.7808546 L122.414069,41.4808546 Z"/></g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
450
docs/erlang.md
Normal file
450
docs/erlang.md
Normal file
@ -0,0 +1,450 @@
|
||||
Erlang 备忘清单
|
||||
===
|
||||
|
||||
[Erlang](https://www.erlang.org/) 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 启动 Erlang Shell
|
||||
|
||||
```shell
|
||||
erl
|
||||
```
|
||||
|
||||
### 编译代码
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```shell
|
||||
# 在 Erlang Shell 中编译
|
||||
c(module).
|
||||
# 在命令行中编译
|
||||
erlc module.erl
|
||||
```
|
||||
|
||||
### 运行代码
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```shell
|
||||
# 在 Erlang Shell 中运行
|
||||
module:function().
|
||||
# 从命令行运行
|
||||
erl -noshell -s module function -s init stop
|
||||
```
|
||||
|
||||
### 退出 Erlang Shell
|
||||
|
||||
```shell
|
||||
q().
|
||||
```
|
||||
|
||||
代码结构
|
||||
---
|
||||
|
||||
### 模块定义
|
||||
|
||||
```erlang
|
||||
-module(module_name).
|
||||
-export([function_name/arity, ...]).
|
||||
|
||||
function_name(Args) ->
|
||||
% Function body.
|
||||
Result.
|
||||
```
|
||||
|
||||
### 导出函数
|
||||
|
||||
```erlang
|
||||
-export([function1/0, function2/1]).
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```erlang
|
||||
% 单行注释
|
||||
% 这是一个注释
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```erlang
|
||||
VarName = Value. % 变量名必须以大写字母开头
|
||||
Age = 25.
|
||||
Name = "Alice".
|
||||
```
|
||||
|
||||
数据类型
|
||||
---
|
||||
|
||||
### 原子
|
||||
|
||||
```erlang
|
||||
atom. % 例子:atom, 'Atom with spaces'
|
||||
```
|
||||
|
||||
### 数字
|
||||
|
||||
```erlang
|
||||
123. % 整数
|
||||
3.14. % 浮点数
|
||||
```
|
||||
|
||||
### 布尔值
|
||||
|
||||
```erlang
|
||||
true.
|
||||
false.
|
||||
```
|
||||
|
||||
### 字符串
|
||||
|
||||
```erlang
|
||||
"Hello, World!".
|
||||
```
|
||||
|
||||
### 元组
|
||||
|
||||
```erlang
|
||||
{ok, "Success"}.
|
||||
```
|
||||
|
||||
### 列表
|
||||
|
||||
```erlang
|
||||
[1, 2, 3].
|
||||
[H|T] = [1, 2, 3]. % H = 1, T = [2, 3]
|
||||
```
|
||||
|
||||
### 字典 (Map)
|
||||
|
||||
```erlang
|
||||
#{key1 => value1, key2 => value2}.
|
||||
```
|
||||
|
||||
控制结构
|
||||
---
|
||||
|
||||
### 条件语句
|
||||
|
||||
```erlang
|
||||
if
|
||||
Condition1 -> Expression1;
|
||||
Condition2 -> Expression2;
|
||||
true -> DefaultExpression
|
||||
end.
|
||||
```
|
||||
|
||||
### case 表达式
|
||||
|
||||
```erlang
|
||||
case Expression of
|
||||
Pattern1 -> Expression1;
|
||||
Pattern2 -> Expression2;
|
||||
_ -> DefaultExpression
|
||||
end.
|
||||
```
|
||||
|
||||
### 函数定义
|
||||
|
||||
```erlang
|
||||
% 无参函数
|
||||
my_function() ->
|
||||
ok.
|
||||
|
||||
% 有参函数
|
||||
add(A, B) ->
|
||||
A + B.
|
||||
```
|
||||
|
||||
列表操作
|
||||
---
|
||||
|
||||
### 列表生成
|
||||
|
||||
```erlang
|
||||
% 生成 1 到 10 的列表
|
||||
[ X || X <- lists:seq(1, 10)].
|
||||
|
||||
% 生成 1 到 10 中的偶数
|
||||
[ X || X <- lists:seq(1, 10), X rem 2 == 0].
|
||||
```
|
||||
|
||||
并发
|
||||
---
|
||||
|
||||
### 启动进程
|
||||
|
||||
```erlang
|
||||
spawn(Module, Function, Args).
|
||||
|
||||
% 示例
|
||||
Pid = spawn(fun() -> io:format("Hello from process~n") end).
|
||||
```
|
||||
|
||||
### 发送消息
|
||||
|
||||
```erlang
|
||||
Pid ! Message.
|
||||
|
||||
% 示例
|
||||
Pid ! {hello, self()}.
|
||||
```
|
||||
|
||||
### 接收消息
|
||||
|
||||
```erlang
|
||||
receive
|
||||
Pattern1 -> Expression1;
|
||||
Pattern2 -> Expression2;
|
||||
after Timeout -> TimeoutExpression
|
||||
end.
|
||||
```
|
||||
|
||||
### 模式匹配
|
||||
|
||||
```erlang
|
||||
{ok, Value} = {ok, 42}.
|
||||
```
|
||||
|
||||
常用内置函数 (BIFs)
|
||||
---
|
||||
|
||||
### 列表操作
|
||||
|
||||
```erlang
|
||||
lists:append(List1, List2).
|
||||
lists:map(Function, List).
|
||||
lists:filter(Function, List).
|
||||
lists:foldl(Function, Acc, List).
|
||||
```
|
||||
|
||||
### 元组操作
|
||||
|
||||
```erlang
|
||||
element(N, Tuple).
|
||||
setelement(N, Tuple, Value).
|
||||
tuple_size(Tuple).
|
||||
```
|
||||
|
||||
### 字符串操作
|
||||
|
||||
```erlang
|
||||
string:len(String).
|
||||
string:concat(String1, String2).
|
||||
string:tokens(String, Delimiters).
|
||||
```
|
||||
|
||||
### 文件操作
|
||||
|
||||
```erlang
|
||||
file:read_file(Filename).
|
||||
file:write_file(Filename, Data).
|
||||
file:delete(Filename).
|
||||
```
|
||||
|
||||
### 列表操作
|
||||
|
||||
```erlang
|
||||
lists:map(fun(X) -> X * 2 end, [1, 2, 3]).
|
||||
lists:filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]).
|
||||
```
|
||||
|
||||
### 字符串操作
|
||||
|
||||
```erlang
|
||||
string:len("Hello").
|
||||
string:upper("hello").
|
||||
```
|
||||
|
||||
### 文件操作
|
||||
|
||||
```erlang
|
||||
{ok, File} = file:open("test.txt", [write]).
|
||||
file:write(File, "Hello, file!").
|
||||
file:close(File).
|
||||
```
|
||||
|
||||
### 示例:简单的服务器
|
||||
|
||||
```erlang
|
||||
-module(server).
|
||||
-export([start/0, loop/0]).
|
||||
|
||||
start() ->
|
||||
spawn(fun loop/0).
|
||||
|
||||
loop() ->
|
||||
receive
|
||||
{echo, Msg} ->
|
||||
io:format("Echo: ~p~n", [Msg]),
|
||||
loop();
|
||||
stop ->
|
||||
io:format("Server stopping~n"),
|
||||
ok;
|
||||
_ ->
|
||||
io:format("Unknown message~n"),
|
||||
loop()
|
||||
end.
|
||||
```
|
||||
|
||||
并发编程
|
||||
---
|
||||
|
||||
### 创建进程
|
||||
|
||||
```erlang
|
||||
Pid = spawn(Module, Function, Args).
|
||||
```
|
||||
|
||||
### 发送消息
|
||||
|
||||
```erlang
|
||||
Pid ! Message.
|
||||
```
|
||||
|
||||
### 接收消息
|
||||
|
||||
```erlang
|
||||
receive
|
||||
Pattern1 -> Actions1;
|
||||
Pattern2 -> Actions2;
|
||||
...
|
||||
end.
|
||||
```
|
||||
|
||||
### 链接进程
|
||||
|
||||
```erlang
|
||||
link(Pid).
|
||||
unlink(Pid).
|
||||
```
|
||||
|
||||
### 监控进程
|
||||
|
||||
```erlang
|
||||
MonitorRef = erlang:monitor(process, Pid).
|
||||
erlang:demonitor(MonitorRef).
|
||||
```
|
||||
|
||||
错误处理
|
||||
---
|
||||
|
||||
### 捕获异常
|
||||
|
||||
```erlang
|
||||
try Expression of
|
||||
Pattern -> Result
|
||||
catch
|
||||
Class:Reason -> Handler
|
||||
end.
|
||||
```
|
||||
|
||||
### 常见异常类型
|
||||
|
||||
- `throw`
|
||||
- `error`
|
||||
- `exit`
|
||||
|
||||
### 错误处理
|
||||
|
||||
```erlang
|
||||
try Expression of
|
||||
Pattern -> Result
|
||||
catch
|
||||
Type:Reason -> ErrorHandlingExpression
|
||||
end.
|
||||
```
|
||||
|
||||
分布式编程
|
||||
---
|
||||
|
||||
### 启动分布式节点
|
||||
|
||||
```shell
|
||||
erl -name nodename@hostname -setcookie Cookie
|
||||
```
|
||||
|
||||
### 连接节点
|
||||
|
||||
```erlang
|
||||
net_adm:ping(Node).
|
||||
```
|
||||
|
||||
### 发送消息到远程节点
|
||||
|
||||
```erlang
|
||||
{remote_process, 'remote_node@host'} ! Message.
|
||||
```
|
||||
|
||||
OTP 框架
|
||||
---
|
||||
|
||||
### 定义 GenServer
|
||||
|
||||
```erlang
|
||||
-module(my_gen_server).
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call(Request, From, State) ->
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(Reason, State) ->
|
||||
ok.
|
||||
|
||||
code_change(OldVsn, State, Extra) ->
|
||||
{ok, State}.
|
||||
```
|
||||
|
||||
### 使用 GenServer
|
||||
|
||||
```erlang
|
||||
gen_server:start_link({local, Name}, Module, Args, Options).
|
||||
gen_server:call(ServerRef, Request).
|
||||
gen_server:cast(ServerRef, Msg).
|
||||
```
|
||||
|
||||
测试
|
||||
---
|
||||
|
||||
### 编写 EUnit 测试
|
||||
|
||||
```erlang
|
||||
-module(module_name_tests).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
simple_test() ->
|
||||
?assertEqual(Expected, Actual).
|
||||
|
||||
complex_test_() ->
|
||||
[
|
||||
{"Test case 1", ?_assertEqual(Expected1, Actual1)},
|
||||
{"Test case 2", ?_assertEqual(Expected2, Actual2)}
|
||||
].
|
||||
```
|
||||
|
||||
### 运行 EUnit 测试
|
||||
|
||||
```shell
|
||||
# 在命令行中运行
|
||||
erl -eval "eunit:test(module_name)" -s init stop
|
||||
```
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Erlang 官方文档](https://www.erlang.org/docs)
|
||||
- [Erlang 编程书籍](https://www.erlang.org/books)
|
419
docs/rxjs.md
Normal file
419
docs/rxjs.md
Normal file
@ -0,0 +1,419 @@
|
||||
RxJS 备忘清单
|
||||
===
|
||||
|
||||
[RxJS](https://rxjs.dev/)(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。
|
||||
|
||||
## 入门
|
||||
|
||||
### 安装 RxJS
|
||||
|
||||
```bash
|
||||
npm install rxjs
|
||||
```
|
||||
|
||||
### 清晰
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
RxJS 的强大之处在于它使用纯函数生成值的能力。这意味着您的代码更不容易出错。通常情况下,您会创建一个不纯的函数,而代码的其他部分可能会弄乱您的状态。
|
||||
|
||||
```js
|
||||
let count = 0;
|
||||
document.addEventListener('click', () => {
|
||||
console.log(`Clicked ${++count} times`)
|
||||
});
|
||||
```
|
||||
|
||||
使用 RxJS 可以隔离状态。
|
||||
|
||||
```js
|
||||
import { fromEvent, scan } from 'rxjs';
|
||||
|
||||
fromEvent(document, 'click')
|
||||
.pipe(scan((count) => count + 1, 0))
|
||||
.subscribe((count) => {
|
||||
console.log(`Clicked ${count} times`)
|
||||
});
|
||||
```
|
||||
|
||||
扫描操作符的工作原理与数组的 `reduce` 类似。它接受一个暴露给回调函数的值。回调的返回值将成为下次回调运行时公开的下一个值。
|
||||
|
||||
### 流
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
RxJS 拥有一整套运算符,可以帮助您控制事件如何流经您的可观察对象。这是使用纯 JavaScript 每秒最多允许一次点击的方式:
|
||||
|
||||
```js
|
||||
let count = 0;
|
||||
let rate = 1000;
|
||||
let lastClick = Date.now() - rate;
|
||||
document.addEventListener('click', () => {
|
||||
if (Date.now() - lastClick >= rate) {
|
||||
console.log(`Clicked ${++count}times`);
|
||||
lastClick = Date.now();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
使用 RxJS:
|
||||
|
||||
```js
|
||||
import { fromEvent, throttleTime, scan
|
||||
} from 'rxjs';
|
||||
|
||||
fromEvent(document, 'click')
|
||||
.pipe(throttleTime(1000),
|
||||
scan((count) => count + 1, 0)
|
||||
)
|
||||
.subscribe((count) => {
|
||||
console.log(`Clicked ${count} times`)
|
||||
});
|
||||
```
|
||||
|
||||
### 第一个示例
|
||||
|
||||
通常情况下,您需要注册事件监听器。
|
||||
|
||||
```js
|
||||
document.addEventListener('click', () => {
|
||||
console.log('Clicked!')
|
||||
});
|
||||
```
|
||||
|
||||
使用 [RxJS](https://rxjs.dev/),您可以创建一个可观察对象。
|
||||
|
||||
```js
|
||||
import { fromEvent } from 'rxjs';
|
||||
|
||||
fromEvent(document, 'click')
|
||||
.subscribe(() => {
|
||||
console.log('Clicked!')
|
||||
});
|
||||
```
|
||||
|
||||
### 导入所需的 Observable 和操作符
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
import { Observable, of, from, interval, fromEvent } from 'rxjs';
|
||||
|
||||
import { map, filter, switchMap, mergeMap, catchError, debounceTime,
|
||||
distinctUntilChanged, take, tap, concatMap, delay, retryWhen, scan,
|
||||
combineLatest, concat, merge, forkJoin, withLatestFrom, startWith, reduce
|
||||
} from 'rxjs/operators';
|
||||
```
|
||||
|
||||
## 创建 Observable
|
||||
|
||||
### of
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
创建一个立即发送指定值并完成的 Observable
|
||||
|
||||
### from
|
||||
|
||||
```javascript
|
||||
const obs = from([1, 2, 3]);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
从 Promise、数组、可迭代对象创建 Observable
|
||||
|
||||
### interval
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000);
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次递增的数字
|
||||
```
|
||||
|
||||
创建一个定时发送递增整数的 Observable
|
||||
|
||||
### fromEvent
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const button = document.querySelector('button');
|
||||
const obs = fromEvent(button, 'click');
|
||||
obs.subscribe(event => {
|
||||
console.log('Button clicked!', event)
|
||||
});
|
||||
```
|
||||
|
||||
从 DOM 事件创建 Observable
|
||||
|
||||
## 操作符
|
||||
|
||||
### map
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
map(x => x * 2)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 2 4 6
|
||||
```
|
||||
|
||||
对 Observable 发出的每个值应用一个函数
|
||||
|
||||
### filter
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
filter(x => x % 2 === 0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 2
|
||||
```
|
||||
|
||||
过滤 Observable 发出的值
|
||||
|
||||
### switchMap
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
switchMap(() => of('Hello'))
|
||||
);
|
||||
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次 "Hello"
|
||||
```
|
||||
|
||||
将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消
|
||||
|
||||
### mergeMap
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
mergeMap(() => of('Hello'))
|
||||
);
|
||||
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次 "Hello"
|
||||
```
|
||||
|
||||
类似 switchMap,但允许多个内部 Observable 并发执行
|
||||
|
||||
### catchError
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
map(x => {
|
||||
if (x === 2) throw 'Error!';
|
||||
return x;
|
||||
}),
|
||||
catchError(err => of('发现一个错误:'+err))
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 发现一个错误:Error!
|
||||
```
|
||||
|
||||
捕获 Observable 链中的错误
|
||||
|
||||
### debounceTime
|
||||
|
||||
```javascript
|
||||
const obs = fromEvent(document,'mousemove')
|
||||
.pipe(debounceTime(300));
|
||||
|
||||
obs.subscribe(event => {
|
||||
console.log('Mouse moved!', event)
|
||||
});
|
||||
```
|
||||
|
||||
延迟处理,直到源 Observable 停止发出数据一定时间
|
||||
|
||||
### distinctUntilChanged
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 1, 2, 2, 3, 3).pipe(
|
||||
distinctUntilChanged()
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
忽略连续重复的值
|
||||
|
||||
### take
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
take(3)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 0 1 2
|
||||
```
|
||||
|
||||
只发出前 n 个值
|
||||
|
||||
## 组合操作符
|
||||
|
||||
### combineLatest
|
||||
|
||||
```javascript
|
||||
const obs1 = interval(1000);
|
||||
const obs2 = of('A', 'B', 'C');
|
||||
const combined = combineLatest(
|
||||
[obs1, obs2]
|
||||
);
|
||||
|
||||
combined.subscribe(console.log);
|
||||
// 每秒输出一次两个 observables 的最新值
|
||||
```
|
||||
|
||||
当两个 Observable 都发出新的值时,发出它们的组合
|
||||
|
||||
### concat
|
||||
|
||||
```javascript
|
||||
const obs1 = of(1, 2, 3);
|
||||
const obs2 = of(4, 5, 6);
|
||||
const combined = concat(obs1, obs2);
|
||||
combined.subscribe(console.log);
|
||||
// 输出: 1 2 3 4 5 6
|
||||
```
|
||||
|
||||
按顺序连接多个 Observable
|
||||
|
||||
### merge
|
||||
|
||||
```javascript
|
||||
const obs1 = interval(1000).pipe(
|
||||
map(x => 'A' + x)
|
||||
);
|
||||
const obs2 = interval(500).pipe(
|
||||
map(x => 'B' + x)
|
||||
);
|
||||
const combined = merge(obs1, obs2);
|
||||
combined.subscribe(console.log);
|
||||
// 每秒输出 "A" 和 "B" 开头的递增数字
|
||||
```
|
||||
|
||||
将多个 Observable 合并为一个
|
||||
|
||||
### forkJoin
|
||||
|
||||
```javascript
|
||||
const obs1 = of(1, 2, 3);
|
||||
const obs2 = of('A', 'B', 'C');
|
||||
const combined = forkJoin([obs1, obs2]);
|
||||
combined.subscribe(console.log);
|
||||
// 输出: [3, 'C']
|
||||
```
|
||||
|
||||
等待所有 Observable 完成,然后发出它们的最后一个值的数组
|
||||
|
||||
## 错误处理
|
||||
|
||||
### retryWhen
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const obs = throwError('出了些问题!')
|
||||
.pipe(
|
||||
retryWhen(errors =>
|
||||
errors.pipe(delayWhen(() => interval(1000)))
|
||||
)
|
||||
);
|
||||
obs.subscribe(console.log, console.error);
|
||||
// 输出: 出了些问题! (每秒重试一次)
|
||||
```
|
||||
|
||||
在 Observable 发出错误时重试
|
||||
|
||||
## 实用操作符
|
||||
|
||||
### tap
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
tap(x => console.log(`Before: ${x}`)),
|
||||
map(x => x * 2),
|
||||
tap(x => console.log(`After: ${x}`))
|
||||
);
|
||||
obs.subscribe();
|
||||
// 输出: Before: 1, After: 2, Before: 2,
|
||||
// After: 4, Before: 3, After: 6
|
||||
```
|
||||
|
||||
用于记录、测量或执行副作用操作
|
||||
|
||||
### startWith
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
startWith(0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 0 1 2 3
|
||||
```
|
||||
|
||||
在 `Observable` 序列前添加值
|
||||
|
||||
### scan
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
scan((acc, value) => acc + value, 0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 3 6
|
||||
```
|
||||
|
||||
对 `Observable` 发出的每个值应用累加器函数
|
||||
|
||||
### reduce
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(reduce((acc, value) => acc + value, 0));
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 6
|
||||
```
|
||||
|
||||
对 `Observable` 发出的值进行累加
|
||||
|
||||
### delay
|
||||
|
||||
```javascript
|
||||
const obs = of('Hello').pipe(delay(2000));
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 'Hello' (延迟2秒)
|
||||
```
|
||||
|
||||
延迟 `Observable` 发出数据的时间
|
||||
|
||||
调度器
|
||||
---
|
||||
|
||||
### 调度器说明
|
||||
|
||||
调度器(Scheduler)控制着 RxJS 操作的执行时机。常见的调度器有:
|
||||
|
||||
- `asyncScheduler`:异步执行任务
|
||||
- `queueScheduler`:按队列顺序执行任务
|
||||
- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(observeOn(asyncScheduler));
|
||||
|
||||
console.log('Before subscribe');
|
||||
obs.subscribe(console.log);
|
||||
console.log('After subscribe');
|
||||
// 输出: Before subscribe, After subscribe, 1, 2, 3
|
||||
```
|
||||
|
||||
## 另见
|
||||
|
||||
- [RxJS 官方文档](https://rxjs.dev/)
|
||||
- [RxJS 学习资源](https://rxjs.dev/guide/overview)
|
||||
- [RxJS 操作符参考](https://rxjs.dev/guide/operators)
|
Reference in New Issue
Block a user