-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
968 lines (456 loc) · 381 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Git Ignore</title>
<link href="/2024/08/11/Git-Ignore/"/>
<url>/2024/08/11/Git-Ignore/</url>
<content type="html"><![CDATA[<h2 id="gitignore-简介"><a href="#gitignore-简介" class="headerlink" title=".gitignore 简介"></a>.gitignore 简介</h2><p><code>.gitignore</code> 文件是 Git 版本控制系统中一个非常实用的功能,用于指定不应该被 Git 跟踪的文件或目录。这通常包括编译生成的二进制文件、临时文件、系统缓存文件、个人配置文件等,这些文件通常不需要保存在版本控制中,因为它们要么是自动生成的,要么是特定于个人环境的。</p><h2 id="gitignore-的用处"><a href="#gitignore-的用处" class="headerlink" title=".gitignore 的用处"></a>.gitignore 的用处</h2><ol><li><strong>节省存储空间</strong>:避免将大量不必要的文件(如编译产物、日志文件)加入仓库,减少仓库大小。</li><li><strong>保护隐私</strong>:防止敏感信息(如密码、密钥、个人配置文件)意外地被提交到公共仓库。</li><li><strong>保持仓库整洁</strong>:仅保留源代码和重要配置文件,便于其他开发者克隆和使用。</li><li><strong>提高效率</strong>:减少 Git 在处理大型仓库时的性能开销。</li></ol><h2 id="gitignore-的用法"><a href="#gitignore-的用法" class="headerlink" title=".gitignore 的用法"></a>.gitignore 的用法</h2><ul><li><strong>模式匹配</strong>:<code>.gitignore</code> 文件中的每一行都是一个匹配模式,用来匹配文件名或目录名。</li><li><strong>注释</strong>:以 <code>#</code> 开头的行被视为注释,不会被解析。</li><li><strong>忽略所有文件</strong>:使用通配符 <code>*</code> 匹配所有文件,例如 <code>*.log</code> 忽略所有 <code>.log</code> 后缀的文件。</li><li><strong>忽略目录</strong>:使用 <code>/</code> 结尾的模式来忽略整个目录,例如 <code>node_modules/</code> 忽略 <code>node_modules</code> 目录下的所有内容。</li><li><strong>排除模式</strong>:如果一行以 <code>!</code> 开头,它会取消之前模式的忽略效果,例如 <code>!important.txt</code> 会将 <code>important.txt</code> 文件从忽略列表中移除。</li><li><strong>多级目录匹配</strong>:使用 <code>/**</code> 可以匹配任意深度的子目录,例如 <code>build/**</code> 忽略 <code>build</code> 目录及其所有子目录下的文件。</li></ul><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><ul><li>如果文件已经被 Git 跟踪,即使后来在 <code>.gitignore</code> 中添加了相应的模式,Git 也不会自动停止跟踪这些文件。需要手动使用 <code>git rm --cached <file></code> 命令来取消跟踪。</li><li><code>.gitignore</code> 文件会被提交到仓库中,这意味着所有贡献者都将遵循相同的忽略规则。</li><li>当创建一个新的 Git 仓库时,通常需要手动创建 <code>.gitignore</code> 文件,<strong>推荐</strong>从 GitHub 或其他平台下载一个适合项目的 <code>.gitignore</code> 模板。</li></ul>]]></content>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>发布-订阅模式</title>
<link href="/2024/08/11/%E5%8F%91%E5%B8%83-%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F/"/>
<url>/2024/08/11/%E5%8F%91%E5%B8%83-%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F/</url>
<content type="html"><![CDATA[<h2 id="发布-订阅模式-Publish-Subscribe-Pattern"><a href="#发布-订阅模式-Publish-Subscribe-Pattern" class="headerlink" title="发布-订阅模式 (Publish-Subscribe Pattern)"></a>发布-订阅模式 (Publish-Subscribe Pattern)</h2><p>发布-订阅模式是一种消息通信模式,它允许多个订阅者监听特定类型的消息,当消息发布时,所有订阅该类型的订阅者都会收到消息。这种模式通常用于异步通信和事件驱动的系统。</p><p><strong>关键角色:</strong></p><ol><li><strong>Publisher(发布者)</strong> 发送消息的对象。</li><li><strong>Subscriber(订阅者)</strong> 接收消息的对象。</li><li><strong>Broker(中间人/事件总线)</strong> 管理发布者和订阅者之间的通信,可以是显式的也可以是隐式的。</li></ol><p>这段代码展示了如何创建一个简单的 <code>EventAggregator</code>类,它允许发布和订阅泛型事件。在实际应用中可能需要更复杂的逻辑来处理线程安全、内存泄漏预防以及更精细的事件管理需求。不过,对于理解基本概念,这个示例应该足够了。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-comment">// 事件聚合器类,用于管理事件的订阅和发布</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EventAggregator</span><br>{<br><span class="hljs-comment">// 存储事件名称与对应的操作列表的字典</span><br> <span class="hljs-keyword">private</span> Dictionary<<span class="hljs-built_in">string</span>, List<Action<<span class="hljs-built_in">string</span>>>> _subscribers = <span class="hljs-keyword">new</span>();<br><span class="hljs-comment">// 订阅事件</span><br><span class="hljs-comment">// eventName: 事件名称</span><br><span class="hljs-comment">// action: 订阅者需要执行的操作</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Subscribe</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName, Action<<span class="hljs-built_in">string</span>> action</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (!_subscribers.ContainsKey(eventName))<br> {<br> _subscribers[eventName] = <span class="hljs-keyword">new</span> List<Action<<span class="hljs-built_in">string</span>>>();<br> }<br> _subscribers[eventName].Add(action);<br> }<br><span class="hljs-comment">// 取消订阅事件</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Unsubscribe</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName, Action<<span class="hljs-built_in">string</span>> action</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (_subscribers.ContainsKey(eventName))<br> {<br> _subscribers[eventName].Remove(action);<br> }<br> }<br><span class="hljs-comment">// 发布事件</span><br><span class="hljs-comment">// eventName: 事件名称</span><br><span class="hljs-comment">// data: 事件数据</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Publish</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName, <span class="hljs-built_in">string</span> data</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (_subscribers.ContainsKey(eventName))<br> {<br> <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> action <span class="hljs-keyword">in</span> _subscribers[eventName])<br> {<br> action(data);<br> }<br> }<br> }<br>}<br><span class="hljs-comment">// 发布者类,负责发布事件</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Publisher</span><br>{<br><span class="hljs-comment">// 依赖的事件聚合器实例</span><br> <span class="hljs-keyword">private</span> EventAggregator _eventAggregator;<br><span class="hljs-comment">// 构造函数,初始化事件聚合器</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Publisher</span>(<span class="hljs-params">EventAggregator eventAggregator</span>)</span><br> {<br> _eventAggregator = eventAggregator;<br> }<br><span class="hljs-comment">// 发布事件的方法</span><br><span class="hljs-comment">// message: 需要发布的事件消息</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PublishEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br> {<br> _eventAggregator.Publish(<span class="hljs-string">"WeatherUpdate"</span>, message);<br> }<br>}<br><span class="hljs-comment">// 订阅者类,负责订阅事件</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Subscriber</span><br>{<br><span class="hljs-comment">// 依赖的事件聚合器实例</span><br> <span class="hljs-keyword">private</span> EventAggregator _eventAggregator;<br><span class="hljs-comment">// 构造函数,初始化事件聚合器,并订阅"WeatherUpdate"事件</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Subscriber</span>(<span class="hljs-params">EventAggregator eventAggregator</span>)</span><br> {<br> _eventAggregator = eventAggregator;<br> _eventAggregator.Subscribe(<span class="hljs-string">"WeatherUpdate"</span>, OnWeatherUpdate);<br> }<br><span class="hljs-comment">// 处理"WeatherUpdate"事件的方法</span><br> <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnWeatherUpdate</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br> {<br> Console.WriteLine(<span class="hljs-string">$"Subscriber received: <span class="hljs-subst">{message}</span>"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><p>实际上使用C#时通常不需要再实现一个 <code>EventAggregator</code> 类,因为C#原生的 <code>event</code> 就已经实现了类似功能。</p><h2 id="使用event"><a href="#使用event" class="headerlink" title="使用event"></a>使用event</h2><p>这种方式更加贴近C#的事件处理机制,同时也简化了管理订阅者逻辑的需求。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-comment">// 定义一个委托类型,用于表示事件处理方法 </span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-built_in">delegate</span> <span class="hljs-keyword">void</span> <span class="hljs-title">WeatherUpdateEventHandler</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span>; <br><span class="hljs-comment">// 发布者类,负责发布事件 </span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Publisher</span> <br>{ <br><span class="hljs-comment">// 使用event关键字定义一个公开的事件,基于之前定义的委托类型 </span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">event</span> WeatherUpdateEventHandler WeatherUpdated; <br><span class="hljs-comment">// 发布事件的方法 </span><br><span class="hljs-comment">// message: 需要发布的事件消息 </span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PublishEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br>{ <br><span class="hljs-comment">// 检查是否有订阅者,如果有则触发事件 </span><br>WeatherUpdated?.Invoke(message); <br>} <br>} <br><span class="hljs-comment">// 订阅者类,负责订阅事件 </span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Subscriber</span> <br>{ <br><span class="hljs-comment">// 订阅Publisher的事件 </span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Subscribe</span>(<span class="hljs-params">Publisher publisher</span>)</span> <br>{ <br>publisher.WeatherUpdated += OnWeatherUpdate; <br>} <br><span class="hljs-comment">// 取消订阅Publisher的事件(如果需要) </span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Unsubscribe</span>(<span class="hljs-params">Publisher publisher</span>)</span> <br>{ <br>publisher.WeatherUpdated -= OnWeatherUpdate; <br>} <br><span class="hljs-comment">// 处理"WeatherUpdate"事件的方法 </span><br><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnWeatherUpdate</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span> <br>{ <br>Console.WriteLine(<span class="hljs-string">$"Subscriber received: <span class="hljs-subst">{message}</span>"</span>); <br>} <br>} <br><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span> <br>{ <br><span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] args</span>)</span> <br>{ <br><span class="hljs-comment">// 实例化发布者和订阅者 </span><br>Publisher publisher = <span class="hljs-keyword">new</span> Publisher(); <br>Subscriber subscriber = <span class="hljs-keyword">new</span> Subscriber(); <br><span class="hljs-comment">// 订阅事件 </span><br>subscriber.Subscribe(publisher); <br><span class="hljs-comment">// 发布事件 </span><br>publisher.PublishEvent(<span class="hljs-string">"It's raining today!"</span>); <br><span class="hljs-comment">// 如果需要,可以在这里调用Unsubscribe方法来取消订阅 </span><br><span class="hljs-comment">// 等待以查看控制台输出 </span><br>Console.ReadKey(); <br>} <br>}<br></code></pre></td></tr></table></figure><p>在C#中,事件(event)机制本身就是用来实现发布-订阅模式的一个强大工具,它允许对象之间进行松耦合的通信。当一个对象(发布者)的状态改变时,它可以触发一个事件,而其他对这个事件感兴趣的对象(订阅者)可以注册处理程序来响应这个事件。这种模式在很多场景下非常有用,尤其是当需要解耦组件并促进模块化设计时。</p><p>尽管如此,在某些复杂的项目或架构中,特别是那些采用如MVVM(Model-View-ViewModel)等设计模式的应用里,可能会发现使用一个 <code>EventAggregator</code> 类更加方便和灵活。<code>EventAggregator</code> 通常作为一个服务存在,允许任何数量的组件发布事件而不必直接引用彼此,同时也能让其他组件订阅这些事件,即使它们之间没有直接的依赖关系。这在大型应用中特别有用,因为它有助于管理大量的事件类型,并且可以更容易地控制事件的生命周期和范围。</p><p>类似于在观察者模式中提到过的,同样的,如果想进一步”简化代码”,可以使用 <code>EventHandler</code> 和 <code>EventArgs</code> 类,这两个类是 C# 中内置的用于事件处理的基类。不过到这一步,观察者模式和发布-订阅模式之间的区别就显得比较模糊了。这两种模式的核心都是关于对象之间的解耦通信,选择哪一种主要取决于设计偏好和项目的具体需求。</p>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>观察者模式</title>
<link href="/2024/08/11/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/"/>
<url>/2024/08/11/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/</url>
<content type="html"><![CDATA[<h2 id="观察者模式-Observer-Pattern"><a href="#观察者模式-Observer-Pattern" class="headerlink" title="观察者模式 (Observer Pattern)"></a>观察者模式 (Observer Pattern)</h2><p>观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式通常用于实现事件处理系统。</p><p><strong>关键角色:</strong></p><ol><li><strong>Subject(主题)</strong> 也称为被观察者,它维护着一个观察者列表,并提供注册、取消注册以及通知观察者的方法。</li><li><strong>Observer(观察者)</strong> 是具体观察者的接口,定义了一个 <code>Update</code>方法来接收主题状态改变的通知。</li></ol><p>以下是为了解释概念而使用接口解释具体机制的代码,实际不会使用这种实现方式,除非你用的是JAVA之类的比较原始的语言。它需要使用接口来定义主题和观察者的行为,适用于需要高度抽象和接口严格分离的情况,代码较为繁琐,但易于扩展。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs Csharp"><span class="hljs-comment">// 观察者模式的主体接口</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">ISubject</span> <br>{ <br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">RegisterObserver</span>(<span class="hljs-params">IObserver observer</span>)</span>; <br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">RemoveObserver</span>(<span class="hljs-params">IObserver observer</span>)</span>; <br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">NotifyObservers</span>()</span>; <br>} <br><span class="hljs-comment">// 观察者接口</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IObserver</span> <br>{ <br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Update</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span>; <br>} <br><span class="hljs-comment">// 实现ISubject接口</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WeatherData</span> : <span class="hljs-title">ISubject</span> <br>{ <br><span class="hljs-comment">// 所有的观察者</span><br><span class="hljs-keyword">private</span> List<IObserver> observers = <span class="hljs-keyword">new</span> List<IObserver>();<br><span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> currentWeather;<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterObserver</span>(<span class="hljs-params">IObserver observer</span>)</span><br>{ <br>observers.Add(observer); <br>}<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RemoveObserver</span>(<span class="hljs-params">IObserver observer</span>)</span><br>{ <br>observers.Remove(observer); <br>}<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">NotifyObservers</span>()</span><br>{<br><span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> observer <span class="hljs-keyword">in</span> observers)<br>{<br>observer.Update(currentWeather);<br>}<br>}<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SetWeather</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> weather</span>)</span><br>{<br><span class="hljs-keyword">this</span>.currentWeather = weather;<br>NotifyObservers();<br>}<br>}<br><span class="hljs-comment">// 实现IObserver接口</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CurrentConditionsDisplay</span> : <span class="hljs-title">IObserver</span> <br>{<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Update</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br>{<br>Console.WriteLine(<span class="hljs-string">$"Current conditions display: <span class="hljs-subst">{message}</span>"</span>);<br>}<br>}<br></code></pre></td></tr></table></figure><p>C#里这么写就太麻烦了,而且高度抽象需要的接口太多,我们有 <code>delegate</code> 和 <code>event</code> 可用</p><h2 id="使用-event-实现观察者模式"><a href="#使用-event-实现观察者模式" class="headerlink" title="使用 event 实现观察者模式"></a>使用 event 实现观察者模式</h2><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-comment">// 定义一个委托,用于处理天气变化的通知</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-built_in">delegate</span> <span class="hljs-keyword">void</span> <span class="hljs-title">WeatherChangedEventHandler</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span>;<br><span class="hljs-comment">// 天气数据类</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WeatherData</span><br>{<br><span class="hljs-comment">// 定义一个事件,当天气变化时触发</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">event</span> WeatherChangedEventHandler WeatherChanged;<br><span class="hljs-comment">// 当前天气状况</span><br><span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> currentWeather;<br><span class="hljs-comment">// 设置天气状况,并通知观察者</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SetWeather</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> weather</span>)</span><br>{<br><span class="hljs-keyword">this</span>.currentWeather = weather;<br>OnWeatherChanged(weather);<br>}<br><span class="hljs-comment">// 触发事件的方法</span><br><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnWeatherChanged</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br>{<br>WeatherChanged?.Invoke(message);<br>}<br>}<br><span class="hljs-comment">// 当前天气状况显示类</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CurrentConditionsDisplay</span><br>{<br><span class="hljs-comment">// 订阅天气变化事件</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CurrentConditionsDisplay</span>(<span class="hljs-params">WeatherData weatherData</span>)</span><br>{<br>weatherData.WeatherChanged += DisplayUpdate;<br>}<br><span class="hljs-comment">// 更新天气状况</span><br><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayUpdate</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> message</span>)</span><br>{<br>Console.WriteLine(<span class="hljs-string">$"Current conditions display: <span class="hljs-subst">{message}</span>"</span>);<br>}<br>}<br></code></pre></td></tr></table></figure><p>如果希望更懒,更伸手就来,则可以不自己定义 <code>delegate</code>,而直接使用C#提供的 <code>EventHandler</code>。</p><h2 id="使用-EventHandler"><a href="#使用-EventHandler" class="headerlink" title="使用 EventHandler"></a>使用 EventHandler</h2><p>除了需要自定义一个事件参数类,继承自 <code>EventArgs</code>,用于封装发生变化的数据,这种方式直接使用了C#的事件处理机制,是更符合语言特性的实践方式。更加简洁,易于理解和使用。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WeatherChangedEventArgs</span> : <span class="hljs-title">EventArgs</span> <br>{ <br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> CurrentWeather { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } <br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WeatherChangedEventArgs</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> currentWeather</span>)</span> <br>{ <br>CurrentWeather = currentWeather; <br>} <br>}<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WeatherData</span> <br>{ <br><span class="hljs-comment">// 使用EventHandler<T>简化事件定义 </span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">event</span> EventHandler<WeatherChangedEventArgs> WeatherChanged; <br><span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> currentWeather; <br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SetWeather</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> weather</span>)</span> <br>{ <br><span class="hljs-keyword">this</span>.currentWeather = weather; <br><span class="hljs-comment">// 触发事件,并传递包含新天气信息的事件参数 </span><br>OnWeatherChanged(<span class="hljs-keyword">new</span> WeatherChangedEventArgs(weather)); <br>} <br><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnWeatherChanged</span>(<span class="hljs-params">WeatherChangedEventArgs e</span>)</span> <br>{ <br>WeatherChanged?.Invoke(<span class="hljs-keyword">this</span>, e); <br>} <br>}<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CurrentConditionsDisplay</span> <br>{ <br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CurrentConditionsDisplay</span>(<span class="hljs-params">WeatherData weatherData</span>)</span> <br>{ <br><span class="hljs-comment">// 订阅WeatherChanged事件 </span><br>weatherData.WeatherChanged += WeatherData_WeatherChanged; <br>} <br><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">WeatherData_WeatherChanged</span>(<span class="hljs-params"><span class="hljs-built_in">object</span> sender, WeatherChangedEventArgs e</span>)</span> <br>{ <br>Console.WriteLine(<span class="hljs-string">$"Current conditions display: <span class="hljs-subst">{e.CurrentWeather}</span>"</span>); <br>} <br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>马基雅维利主义者</title>
<link href="/2024/07/24/%E9%A9%AC%E5%9F%BA%E9%9B%85%E7%BB%B4%E5%88%A9%E4%B8%BB%E4%B9%89%E8%80%85/"/>
<url>/2024/07/24/%E9%A9%AC%E5%9F%BA%E9%9B%85%E7%BB%B4%E5%88%A9%E4%B8%BB%E4%B9%89%E8%80%85/</url>
<content type="html"><![CDATA[<p>马基雅维利主义者(Machiavellian)通常指那些在政治或商业中采取实用主义和策略性手段的人,以达到自己的目标,而不拘泥于道德或伦理原则。这个词源自意大利文艺复兴时期政治理论家尼科洛·马基雅维利(Niccolò Machiavelli)及其著作《君主论》(The Prince)。</p><p>在《君主论》中,马基雅维利提出了一些关于权力和统治的实用主义观点,例如:</p><ol><li><strong>权力的获取和维持</strong>:他强调君主应当使用各种手段来获取和维持权力,包括欺骗、操控和暴力。</li><li><strong>实用主义</strong>:他认为成功的统治者应根据实际情况采取灵活的策略,而不是严格遵循道德或伦理准则。</li><li><strong>“目的决定手段”</strong>:马基雅维利主张,统治者为了维护国家和自己的权力,可以不择手段,这种观点常被概括为“目的决定手段”。</li></ol><h3 id="特征"><a href="#特征" class="headerlink" title="特征"></a>特征</h3><p>马基雅维利主义者通常具有以下特征:</p><ol><li><strong>操控性</strong>:善于操控和利用他人,以实现自己的目标。</li><li><strong>冷酷无情</strong>:不被情感或道德约束,采取冷酷无情的手段来解决问题。</li><li><strong>权力导向</strong>:高度关注权力的获取和维持,倾向于通过权谋和策略来实现自己的利益。</li><li><strong>策略性思维</strong>:注重长远规划和策略性思维,善于权衡利弊并采取最有效的行动。</li></ol><h3 id="马基雅维利主义的应用"><a href="#马基雅维利主义的应用" class="headerlink" title="马基雅维利主义的应用"></a>马基雅维利主义的应用</h3><ol><li><strong>政治</strong>:在政治领域,马基雅维利主义者可能会通过权谋、操控和战略联盟来获取和维持权力。</li><li><strong>商业</strong>:在商业领域,马基雅维利主义者可能会通过操控市场、竞争对手和内部资源来实现商业目标。</li><li><strong>个人关系</strong>:在个人关系中,马基雅维利主义者可能会利用他人、操控情感和信息来获得个人利益。</li></ol><h3 id="批评与争议"><a href="#批评与争议" class="headerlink" title="批评与争议"></a>批评与争议</h3><p>马基雅维利主义因其无情和实用主义的性质而受到广泛批评,被认为是一种缺乏道德的权力观。然而,马基雅维利主义的支持者则认为,在复杂和竞争激烈的环境中,实用主义和灵活性是取得成功的关键。</p><p>总结而言,马基雅维利主义者是一类注重实际效果和权力策略的人,他们以不拘泥于传统道德原则的方式来实现目标。这一概念在政治、商业和个人生活中都有着广泛的影响和应用。</p><h2 id="费曼学习法解释马基雅维利主义"><a href="#费曼学习法解释马基雅维利主义" class="headerlink" title="费曼学习法解释马基雅维利主义"></a>费曼学习法解释马基雅维利主义</h2><h3 id="1-简单地解释概念"><a href="#1-简单地解释概念" class="headerlink" title="1. 简单地解释概念"></a>1. 简单地解释概念</h3><p><strong>什么是马基雅维利主义?</strong></p><p>马基雅维利主义是一种以实用主义和策略性手段为核心的政治和商业理论。它得名于意大利政治理论家尼科洛·马基雅维利(Niccolò Machiavelli),特别是他的著作《君主论》(The Prince)。这个理论强调,为了达到目的,可以不拘泥于道德或伦理原则。简单来说,就是“目的可以决定手段”。</p><h3 id="2-教一个孩子"><a href="#2-教一个孩子" class="headerlink" title="2. 教一个孩子"></a>2. 教一个孩子</h3><p><strong>如何向一个小孩解释马基雅维利主义?</strong></p><p>假设你在学校玩一场游戏,你非常想赢。但是你发现,要想赢得游戏,你可能需要做一些不太好的事情,比如撒谎或欺骗别人。虽然你知道这些事情是不对的,但你还是决定这么做,因为你觉得赢得游戏比遵守规则更重要。这种为了赢得游戏而不顾规则的行为,就有点像马基雅维利主义。</p><h3 id="3-更深入地理解"><a href="#3-更深入地理解" class="headerlink" title="3. 更深入地理解"></a>3. 更深入地理解</h3><p><strong>马基雅维利主义的主要特征是什么?</strong></p><ol><li><strong>操控性</strong>:马基雅维利主义者善于操控和利用他人,以实现自己的目标。</li><li><strong>冷酷无情</strong>:他们不被情感或道德约束,采取冷酷无情的手段来解决问题。</li><li><strong>权力导向</strong>:他们高度关注权力的获取和维持,倾向于通过权谋和策略来实现自己的利益。</li><li><strong>策略性思维</strong>:他们注重长远规划和策略性思维,善于权衡利弊并采取最有效的行动。</li></ol><h3 id="4-将概念与日常生活联系起来"><a href="#4-将概念与日常生活联系起来" class="headerlink" title="4. 将概念与日常生活联系起来"></a>4. 将概念与日常生活联系起来</h3><p><strong>马基雅维利主义在日常生活中的例子</strong></p><ul><li><strong>在学校</strong>:一个学生为了当上班长,故意在老师面前揭发同学的小错误,尽管这些错误并没有影响大家的生活。</li><li><strong>在公司</strong>:一个员工为了升职,背后说同事的坏话,或者故意隐瞒同事的好表现。</li><li><strong>在政治中</strong>:一个政客为了获得选票,承诺许多不切实际的政策,或者揭露对手的隐私。</li></ul>]]></content>
<tags>
<tag>政治经济学</tag>
</tags>
</entry>
<entry>
<title>拉格朗日乘法</title>
<link href="/2024/07/24/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E4%B9%98%E6%B3%95/"/>
<url>/2024/07/24/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E4%B9%98%E6%B3%95/</url>
<content type="html"><![CDATA[<h1 id="拉格朗日乘法"><a href="#拉格朗日乘法" class="headerlink" title="拉格朗日乘法"></a>拉格朗日乘法</h1><p>拉格朗日乘法(Lagrange Multipliers)是一种在有约束条件下的优化问题中寻找极值点的方法。这种方法通过引入拉格朗日乘数(λ),将原来的有约束优化问题转化为无约束优化问题。具体来说,如果有函数f(x, y)需要在满足g(x, y) = c的条件下最大化或最小化,其中x和y是变量,c是常数,g(x, y)是约束条件,那么可以构造拉格朗日函数L(x, y, λ):</p><p>$$<br>L(x,y,\lambda)=f(x,y)−\lambda(g(x,y)−c)<br>$$</p><p>然后,我们通过求解下面的方程组来找到可能的极值点:</p><p>$\frac{∂𝐿}{∂𝑥}=0$,$\frac{∂𝐿}{∂𝑦}=0$,$\frac{∂L}{∂\lambda}=0$</p><p>这对应于找到使得L关于x、y和λ的偏导数都为0的点(x, y, λ)。</p>]]></content>
</entry>
<entry>
<title>费曼学习法</title>
<link href="/2024/07/24/%E8%B4%B9%E6%9B%BC%E5%AD%A6%E4%B9%A0%E6%B3%95/"/>
<url>/2024/07/24/%E8%B4%B9%E6%9B%BC%E5%AD%A6%E4%B9%A0%E6%B3%95/</url>
<content type="html"><![CDATA[<h1 id="费曼学习法"><a href="#费曼学习法" class="headerlink" title="费曼学习法"></a>费曼学习法</h1><h2 id="用普通的方式解释费曼学习法"><a href="#用普通的方式解释费曼学习法" class="headerlink" title="用普通的方式解释费曼学习法"></a>用普通的方式解释费曼学习法</h2><p>费曼学习法是由诺贝尔物理学奖得主理查德·费曼(Richard Feynman)提出的一种学习方法。它的核心思想是通过教授他人来检验和巩固自己的知识。这个方法包括以下几个步骤:</p><ol><li><strong>选择一个概念</strong>:选择你想要学习或理解的一个主题或概念。</li><li><strong>教别人</strong>:假装你在教一个对这个主题完全不了解的人,比如一个小孩。用最简单的语言解释这个概念。</li><li><strong>找出漏洞</strong>:在解释过程中,注意自己无法解释清楚或不理解的部分。这些就是你知识的漏洞。</li><li><strong>回顾和简化</strong>:回头查阅资料,弄清楚这些漏洞,然后再次用简单的语言进行解释。不断重复这个过程,直到你能够清晰地解释整个概念。</li></ol><h2 id="用费曼学习法的方式解释费曼学习法"><a href="#用费曼学习法的方式解释费曼学习法" class="headerlink" title="用费曼学习法的方式解释费曼学习法"></a>用费曼学习法的方式解释费曼学习法</h2><p><strong>1. 简单地解释概念</strong></p><p>费曼学习法是一种学习方法,通过教别人来巩固自己的知识。如果你能把一个复杂的概念用简单的语言教给别人,你就真正理解了这个概念。</p><p><strong>2. 教一个孩子</strong></p><p>假设你学会了一个新的数学公式。你要想真正理解它,可以试着把它教给你的弟弟或妹妹。如果你能用很简单的话让他们明白这个公式的意思,那么你就真的理解了这个公式。如果你发现有些部分解释不清楚,那就说明你还需要再学一学。</p><p><strong>3. 更深入地理解</strong></p><p>费曼学习法的核心步骤是:</p><ul><li>选择一个你想学的主题。</li><li>假装教一个完全不懂这个主题的人,用最简单的语言解释。</li><li>在这个过程中,注意到你解释不清楚的部分,那就是你不理解的地方。</li><li>回去重新学习这些不理解的部分,然后再试着解释一遍。</li></ul><p><strong>4. 将概念与日常生活联系起来</strong></p><p>比如,你在学历史课上的一个事件。你可以试着把这个事件讲给你的朋友听。如果你能用简单易懂的语言把这个事件讲清楚,那就说明你理解了。如果有些地方你讲不清楚,那就回去再学一学,直到你能讲清楚为止。</p><p><strong>5. 回顾和总结</strong></p><p>总结来说,费曼学习法是通过教授别人来检验和巩固自己知识的方法。这个方法的步骤包括选择一个主题、用简单语言教别人、找出自己不理解的部分、回去学习这些部分,然后再教一遍。通过这个过程,你可以更好地理解和掌握新的知识。</p>]]></content>
<tags>
<tag>学习方法</tag>
</tags>
</entry>
<entry>
<title>杜邦分析</title>
<link href="/2024/07/24/%E6%9D%9C%E9%82%A6%E5%88%86%E6%9E%90/"/>
<url>/2024/07/24/%E6%9D%9C%E9%82%A6%E5%88%86%E6%9E%90/</url>
<content type="html"><![CDATA[<h1 id="杜邦分析"><a href="#杜邦分析" class="headerlink" title="杜邦分析"></a>杜邦分析</h1><p>杜邦分析(DuPont Analysis)是一种财务比率分析方法,主要用于分解公司的净资产收益率(Return on Equity, ROE),以便更深入地理解ROE的各个组成部分,从而洞察公司盈利能力和财务结构。杜邦分析将ROE分解为三个关键比率:利润率(Profit Margin)、资产周转率(Asset Turnover)和财务杠杆(Financial Leverage)。这个分析框架有助于管理层和投资者识别公司业绩的驱动因素,并对比同行表现。</p><h3 id="杜邦分析的三个组成部分:"><a href="#杜邦分析的三个组成部分:" class="headerlink" title="杜邦分析的三个组成部分:"></a>杜邦分析的三个组成部分:</h3><ol><li><strong>利润率(Profit Margin)</strong>:衡量每单位销售额产生的净利润,即净利润与销售收入的比率。高利润率表示公司能够有效地将其销售收入转化为利润。</li><li><strong>资产周转率(Asset Turnover)</strong>:反映公司利用资产产生销售收入的效率,即销售收入与平均总资产的比率。高资产周转率意味着公司能更高效地运用其资产。</li><li><strong>财务杠杆(Financial Leverage)</strong>:表示公司如何使用债务融资来增加股东回报,即平均总资产与股东权益的比率。财务杠杆放大了ROE,但也增加了财务风险。</li></ol><h3 id="杜邦分析的计算公式:"><a href="#杜邦分析的计算公式:" class="headerlink" title="杜邦分析的计算公式:"></a>杜邦分析的计算公式:</h3><p>ROE = 利润率 × 资产周转率 × 财务杠杆</p><p>更详细的分解如下:</p><p>ROE=(净利润销售收入)×(销售收入平均总资产)×(平均总资产股东权益)ROE=(销售收入净利润)×(平均总资产销售收入)×(股东权益平均总资产)</p><h3 id="分析步骤:"><a href="#分析步骤:" class="headerlink" title="分析步骤:"></a>分析步骤:</h3><ol><li><p><strong>计算ROE</strong>:ROE = 净利润 / 股东权益</p></li><li><p><strong>分解ROE</strong>:</p><ul><li>计算利润率:净利润 / 销售收入</li><li>计算资产周转率:销售收入 / 平均总资产</li><li>计算财务杠杆:平均总资产 / 股东权益</li></ul></li><li><p><strong>分析各比率</strong>:比较这些比率与行业平均水平,以及公司历史数据,识别优势和劣势。</p></li><li><p><strong>采取措施</strong>:基于分析结果,公司可以制定策略来改善利润率、资产使用效率或资本结构。</p></li></ol><p>杜邦分析不仅提供了对ROE的深入理解,还能帮助企业发现其业务模式中的强项和弱点,从而指导战略决策。通过将ROE分解为更细的组成部分,管理者可以聚焦于特定的财务比率,以优化整体财务绩效。</p>]]></content>
<tags>
<tag>商业</tag>
</tags>
</entry>
<entry>
<title>Windows快捷键</title>
<link href="/2024/07/24/Windows%E5%BF%AB%E6%8D%B7%E9%94%AE/"/>
<url>/2024/07/24/Windows%E5%BF%AB%E6%8D%B7%E9%94%AE/</url>
<content type="html"><![CDATA[<p>微软虽然没有在桌面上放一个文件或者给一个用户手册告诉你有哪些快捷键,但他们的网站上还是很详细的。</p><p><a href="https://support.microsoft.com/zh-cn/windows/windows-%E7%9A%84%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F-dcc61a57-8ff0-cffe-9796-cb9706c75eec">Windows 的键盘快捷方式 - Microsoft 支持</a></p><p>列举一些常用的,像什么复制粘贴之类的就不赘述了。</p><ul><li>ctrl+退格:一次删除整个单词,而不是多次按退格键</li><li>windows+shift+s:截屏,保存到剪贴板</li><li>ctrl+shift+windows+b:用于软图形驱动复位,适用于当你将笔记本电脑插入基座时,它不能正确的连接显示器,节省了打开/关闭盖子或插/拔接头的时间</li><li>windows+v:查看剪贴板中的所有内容</li><li>windows+方向键,快速将窗口设为最大化、最小化、半屏、四分之一屏。</li><li>windows+L:锁定,进入锁屏界面</li><li>windows+D:显示桌面</li><li>windows+空格:清除被选中文本的格式</li><li>ctrl+shift+T:恢复上一个被关闭的窗口</li><li>机箱上这个可弹出式的杯架也可以用来播放CD光盘💿</li><li>alt-code:按住alt键的同时在数字键盘输入代号,即可输入特殊字符,像是制表符、数学符号、希腊字母等。</li><li>ctrl+tab:在浏览器中切换选项卡</li><li>alt+tab:在程序窗口之间切换</li><li>ctrl+shift+escape:打开任务管理器</li><li>windows+alt+prtsc:截图当前活动窗口</li><li>windows+句号键:表情符号,当然也可以输入颜文字和特殊符号</li><li>windows+P:多显示器设置</li><li>摇晃:在桌面上,如果你打开了很多窗口,而你只想专注于一个窗口,你可以抓住你想专注的窗口,然后晃一晃它,其他所有窗口都会最小化,再摇一摇,他们就又回来了。</li></ul>]]></content>
<tags>
<tag>Windows</tag>
</tags>
</entry>
<entry>
<title>Therac-25事件</title>
<link href="/2024/07/24/Therac-25%E6%A1%88%E4%BE%8B/"/>
<url>/2024/07/24/Therac-25%E6%A1%88%E4%BE%8B/</url>
<content type="html"><![CDATA[<h1 id="Therac-25事件"><a href="#Therac-25事件" class="headerlink" title="Therac-25事件"></a>Therac-25事件</h1><p>Therac-25事件是在软件工程界被大量引用的案例。Therac-25是加拿大原子能有限公司(AECL)所生产的放射线疗法机器,在Therac-6和Therac-20之后推出(以往的Therac-6和Therac-20是加拿大原子能有限公司和法国的CGL公司合作开发)。在1985年到1987年之间,在美国及加拿大至少有六起和Therac-25相关的医疗事故,因为软件设计时的瑕疵,使病人受到了过量的辐射。软件的瑕疵是因为竞争危害(二个同时进行程序之间时序冲突造成的问题),有瑕疵时会使病患接受到比正常剂量高一百倍的辐射,因此造成患者死亡或重伤。<br>此一事故突显了安全关键系统若使用软件控制时的潜在危险性,也是软件工程及医学信息学的经典案例。另外因为工程师的过度自信,而且没有进行适当的尽职调查来修复已知的软件问题,这也是一个极端的例子,工程师因为对其初期的工程过度自信,没有相信终端用户提出的问题,最后产生了严重的结果。Therac-25事件后,软件开发工程化管理方法论开始得到重视。</p><h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><p>此事件发生时,所发射的是高能量的电子束,而不是预期的低能量电子束,而且设备对应的零件没有让电子束进入X射线腔中。以前的机种有硬件互锁机制以避免这种情形发生,而Therac-25取消了硬件互锁机制,为了安全起见改用软件的互锁机制。软件互锁机制在有竞争危害时会失效。其缺陷如下:有一个测试程序中一字节的计数器常常会溢出,若操作员恰好在计数器溢出时输入命令,软件互锁机制会失效。<br>高能量的电子束给予的能量是理想辐射剂量的100倍,是可能会造成β辐射的致命剂量。患者Ray Cox描述其感觉像“强烈的电击”,他因此尖叫跑出诊疗室。几天后病人开始出现辐射灼伤,病人也开始出现辐射过量的症状,其中有三个病患后来因为辐射过量而死亡。</p>]]></content>
<tags>
<tag>软件工程</tag>
</tags>
</entry>
<entry>
<title>Unity ScriptableObject简介</title>
<link href="/2024/07/24/Unity%20ScriptableObject/"/>
<url>/2024/07/24/Unity%20ScriptableObject/</url>
<content type="html"><![CDATA[<p>ScriptableObject就是可以Script的Object(废话)。这里的script不是指脚本,而是序列化(binary)的。<br>它的主要作用有三个:</p><ul><li>编辑模式下的数据持久化</li><li>配置文件(配置游戏中的数据)</li><li>数据复用(多个对象公用一套数据)</li></ul><h2 id="ScriptableObject的特点和用途:"><a href="#ScriptableObject的特点和用途:" class="headerlink" title="ScriptableObject的特点和用途:"></a>ScriptableObject的特点和用途:</h2><ol><li><strong>数据共享与复用</strong>:多个脚本或组件可以引用同一个 <code>ScriptableObject</code> 实例,便于在整个项目中共享数据。</li><li><strong>编辑器友好</strong>:可以在Unity编辑器内直接查看和编辑 <code>ScriptableObject</code> 的字段,便于非程序员调整数据。</li><li><strong>版本控制友好</strong>:作为资产文件存在,易于团队协作和版本管理。</li><li><strong>数据驱动设计</strong>:非常适合用来实现配置、预设、关卡数据、物品列表等不需要绑定到特定游戏对象的数据结构。</li></ol><h2 id="一个典型的ScriptableObject类"><a href="#一个典型的ScriptableObject类" class="headerlink" title="一个典型的ScriptableObject类"></a>一个典型的ScriptableObject类</h2><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs Csharp"><span class="hljs-keyword">using</span> UnityEngine; <br>[<span class="hljs-meta">CreateAssetMenu(fileName = <span class="hljs-string">"New MyData"</span>, menuName = <span class="hljs-string">"MyData/MyData"</span>)</span>]<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MyData</span> : <span class="hljs-title">ScriptableObject</span> <br>{ <br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> someString;<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> someInt; <br><span class="hljs-comment">// 可以添加更多公开字段或属性 </span><br>}<br></code></pre></td></tr></table></figure><h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs Csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MyUser</span> : <span class="hljs-title">MonoBehaviour</span><br>{ <br><span class="hljs-keyword">public</span> MyData myDataReference; <br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>()</span> <br>{ <br>Debug.Log(myDataReference.someString);<br>Debug.Log(myDataReference.someInt); <br>} <br>}<br></code></pre></td></tr></table></figure><h2 id="静态函数"><a href="#静态函数" class="headerlink" title="静态函数"></a>静态函数</h2><p><code>ScriptableObject.CreatInstance<\T>()</code> 是Unity的一个静态方法,它的主要作用是动态地创建一个指定类型的<code>ScriptableObject</code>实例。这个方法对于在运行时根据需要创建数据容器、配置对象或预设非常有用。</p><h2 id="消息函数"><a href="#消息函数" class="headerlink" title="消息函数"></a>消息函数</h2><ul><li>Awake</li><li>OnDestory</li><li>OnDisable</li><li>Onenable</li><li>Onvalidate Editor-only function that Unity calls when the script is loaded or a value changes in the Inspector.仅编辑器模式下当脚本加载或值改变时编辑器调用此函数</li><li>Reset</li></ul>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>Unity MVC框架</title>
<link href="/2024/07/24/Unity%20MVC%E6%A1%86%E6%9E%B6/"/>
<url>/2024/07/24/Unity%20MVC%E6%A1%86%E6%9E%B6/</url>
<content type="html"><![CDATA[<h2 id="一、介绍MVC"><a href="#一、介绍MVC" class="headerlink" title="一、介绍MVC"></a>一、介绍MVC</h2><p>MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。</p><p>MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。</p><p>Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。<br> 通常模型对象负责在数据库中存取数据。</p><p>View(视图)是应用程序中处理数据显示的部分。<br> 通常视图是依据模型数据创建的。</p><p>Controller(控制器)是应用程序中处理用户交互的部分。<br> 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。</p><h2 id="二、代码实现(基于Unity)"><a href="#二、代码实现(基于Unity)" class="headerlink" title="二、代码实现(基于Unity)"></a>二、代码实现(基于Unity)</h2><blockquote><p>有事件管理中心(class MVC)的MVC模式实现</p></blockquote><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> System;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><span class="hljs-keyword">using</span> System.Linq;<br><span class="hljs-keyword">using</span> System.Text;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Model</span><br>{<br> <span class="hljs-comment">//名字标识</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-built_in">string</span> Name { <span class="hljs-keyword">get</span>; }<br> <br> <span class="hljs-comment">//发送事件</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName,<span class="hljs-built_in">object</span> data=<span class="hljs-literal">null</span></span>)</span><br> {<br> MVC.SendEvent(eventName, data);<br> }<br>}<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> System.Collections;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><span class="hljs-keyword">using</span> UnityEngine;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">View</span> : <span class="hljs-title">MonoBehaviour</span> {<br> <br> <span class="hljs-comment">//名字标识</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-built_in">string</span> Name { <span class="hljs-keyword">get</span>; }<br> <br> <span class="hljs-comment">//事件关心列表</span><br> [<span class="hljs-meta">HideInInspector</span>]<br> <span class="hljs-keyword">public</span> List<<span class="hljs-built_in">string</span>> AttentionList = <span class="hljs-keyword">new</span> List<<span class="hljs-built_in">string</span>>();<br> <br> <span class="hljs-comment">//初始化事件关心列表,在注册视图的时候被调用</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterAttentionEvent</span>()</span> { }<br> <br> <span class="hljs-comment">//处理事件</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">HandleEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> name, <span class="hljs-built_in">object</span> data</span>)</span>;<br> <br> <span class="hljs-comment">//发送事件</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName, <span class="hljs-built_in">object</span> data = <span class="hljs-literal">null</span></span>)</span><br> {<br> MVC.SendEvent(eventName, data);<br> }<br> <br> <span class="hljs-comment">//获取模型</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> T <span class="hljs-title">GetModel</span><<span class="hljs-title">T</span>>()</span><br><span class="hljs-function"> <span class="hljs-keyword">where</span> T:Model</span><br> {<br> <span class="hljs-keyword">return</span> MVC.GetModel<T>() <span class="hljs-keyword">as</span> T;<br> }<br> <br> <br>}<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> System;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><span class="hljs-keyword">using</span> System.Linq;<br><span class="hljs-keyword">using</span> System.Text;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Controller</span><br>{<br> <span class="hljs-comment">//执行事件</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Execute</span>(<span class="hljs-params"><span class="hljs-built_in">object</span> data</span>)</span>;<br> <br> <span class="hljs-comment">//获取模型</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> T <span class="hljs-title">GetModel</span><<span class="hljs-title">T</span>>()</span><br><span class="hljs-function"> <span class="hljs-keyword">where</span> T : Model</span><br> {<br> <span class="hljs-keyword">return</span> MVC.GetModel<T>() <span class="hljs-keyword">as</span> T;<br> }<br> <br> <span class="hljs-comment">//获取视图</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> T <span class="hljs-title">GetView</span><<span class="hljs-title">T</span>>()</span><br><span class="hljs-function"> <span class="hljs-keyword">where</span> T : View</span><br> {<br> <span class="hljs-keyword">return</span> MVC.GetView<T>() <span class="hljs-keyword">as</span> T;<br> }<br> <span class="hljs-comment">//注册模型</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterModel</span>(<span class="hljs-params">Model model</span>)</span><br> {<br> MVC.RegisterModel(model);<br> }<br> <span class="hljs-comment">//注册视图</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterView</span>(<span class="hljs-params">View view</span>)</span><br> {<br> MVC.RegisterView(view); <br> }<br> <span class="hljs-comment">//注册控制器</span><br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterController</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName,Type controllerType</span>)</span><br> {<br> MVC.RegisterController(eventName, controllerType);<br> }<br> <br>}<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> System;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><span class="hljs-keyword">using</span> System.Linq;<br><span class="hljs-keyword">using</span> System.Text;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MVC</span><br>{<br> <span class="hljs-comment">//资源</span><br> <span class="hljs-comment">//名字 -- model(保存的是实例对象)</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Dictionary<<span class="hljs-built_in">string</span>, Model> Models = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">string</span>, Model>();<br> <span class="hljs-comment">//名字 -- view(保存的是实例对象)</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Dictionary<<span class="hljs-built_in">string</span>, View> Views = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">string</span>, View>();<br> <span class="hljs-comment">//事件名字 -- 类型 (保存的是类)</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Dictionary<<span class="hljs-built_in">string</span>, Type> ComandMap = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">string</span>, Type>();<br> <br> <span class="hljs-comment">//注册view,注意这里的view其实是由 继承于View的子类上溯而来(下同)</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterView</span>(<span class="hljs-params">View view</span>)</span><br> {<br> <span class="hljs-comment">//防止view的重复注册</span><br> <span class="hljs-keyword">if</span>(Views.ContainsKey(view.Name))<br> {<br> Views.Remove(view.Name);<br> }<br> view.RegisterAttentionEvent();<span class="hljs-comment">//调用视图方法,注册视图关心事件,存放在关心事件列表中</span><br> Views[view.Name] = view;<br> }<br> <br> <span class="hljs-comment">//注册model</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterModel</span>(<span class="hljs-params">Model model</span>)</span><br> {<br> Models[model.Name] = model;<br> }<br> <br> <span class="hljs-comment">//注册controller 将一个事件执行器放入字典,以eventName为键,Type类型是类,就是放入一个需要被实例化的类,使用的时候必须要实例化再使用</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterController</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName,Type controllerType</span>)</span><br> {<br> ComandMap[eventName] = controllerType;<br> }<br> <br> <span class="hljs-comment">//获取model,T是外部传进来的模型脚本,该脚本必须继承自Model</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> T <span class="hljs-title">GetModel</span><<span class="hljs-title">T</span>>()</span><br><span class="hljs-function"> <span class="hljs-keyword">where</span> T:Model</span><br> {<br> <span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">var</span> m <span class="hljs-keyword">in</span> Models.Values)<br> {<br> <span class="hljs-comment">//m肯定是Model类型,但是这个m 是由 继承于Model的脚本上溯而来的,这里会进行下溯 看看m是否等于T</span><br> <span class="hljs-keyword">if</span> (m <span class="hljs-keyword">is</span> T)<br> {<br> <span class="hljs-comment">//若等于,则先强转为T脚本 再返回.</span><br> <span class="hljs-keyword">return</span> (T)m;<br> }<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <br> <span class="hljs-comment">//获取view</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> T <span class="hljs-title">GetView</span><<span class="hljs-title">T</span>>()</span><br><span class="hljs-function"> <span class="hljs-keyword">where</span> T : View</span><br> {<br> <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> v <span class="hljs-keyword">in</span> Views.Values)<br> {<br> <span class="hljs-keyword">if</span> (v <span class="hljs-keyword">is</span> T)<br> {<br> <span class="hljs-keyword">return</span> (T)v;<br> }<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <br> <span class="hljs-comment">//发送事件(对于外部调用者来说该方法是发送事件,对于内部方法来说是不同的控制器和视图处理事件),命名上不要求和我一致,只要见名知意即可.</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEvent</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> eventName,<span class="hljs-built_in">object</span> data=<span class="hljs-literal">null</span></span>)</span><br> {<br> <span class="hljs-comment">//在这里可发现一个事件对应一个Controller处理,具体事件继承于抽象事件,一个具体事件的诞生首先要进行继承于Controller 重写Execute 注册入CommandMap字典三步骤</span><br> <span class="hljs-comment">//controller 执行,eventName是事件名称,若在控制器字典内存在该事件名称,则肯定会有一个控制器去处理该事件</span><br> <span class="hljs-keyword">if</span>(ComandMap.ContainsKey(eventName))<br> {<br> <span class="hljs-comment">//t脚本类是继承于Controller类的,不然下面无法转换为Controller</span><br> Type t = ComandMap[eventName];<br> <span class="hljs-comment">//根据字典取出来的t,去实例化一个对象,并且object转化为Controller类型,因为t对象继承于Controller所以可以转化</span><br> Controller c = Activator.CreateInstance(t) <span class="hljs-keyword">as</span> Controller; <br> <span class="hljs-comment">//执行被t所重写的Execute方法,data是传入的数据(object类型)</span><br> c.Execute(data);<br> }<br> <span class="hljs-comment">//view处理</span><br> <span class="hljs-comment">//遍历所有视图,注意:一个视图允许有多个事件,而且一个事件可能会在不同的视图触发,而事件的内容不确定(事件可理解为触发消息)</span><br> <span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">var</span> v <span class="hljs-keyword">in</span> Views.Values)<br> {<br> <span class="hljs-comment">//视图v的关心事件列表中存在该事件</span><br> <span class="hljs-keyword">if</span>(v.AttentionList.Contains(eventName))<br> {<br> <span class="hljs-comment">//让视图v执行该事件eventName,附带参数data</span><br> <span class="hljs-comment">//HandleEvent方法是通过switch case的形式处理不同的事件</span><br> v.HandleEvent(eventName, data);<br> }<br> }<br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>Unity ECS简介</title>
<link href="/2024/07/24/Unity%20ECS%E7%AE%80%E4%BB%8B/"/>
<url>/2024/07/24/Unity%20ECS%E7%AE%80%E4%BB%8B/</url>
<content type="html"><![CDATA[<h2 id="什么是Unity-ECS"><a href="#什么是Unity-ECS" class="headerlink" title="什么是Unity ECS"></a>什么是Unity ECS</h2><p>Unity ECS是Unity引擎中的一种高性能游戏开发架构,它采用了<strong>基于数据的设计思路</strong>,与传统的面向对象编程不同。它的目标是提高游戏的性能和可伸缩性。</p><p>Unity ECS通过[[#实体(Entity)]]、[[#组件(Component)]]和[[#系统(System)]]这三个概念来描述游戏对象。实体是游戏对象的<strong>标识符</strong>,组件是游戏对象的<strong>属性</strong>,系统是对实体和组件的<strong>操作</strong>。</p><p>Unity ECS与传统的面向对象编程不同,主要体现在以下方面:</p><ul><li>面向数据:ECS是一种基于数据的编程模型,它着重于描述游戏对象的属性和行为,而不是游戏对象本身。这使得ECS能够更加高效地处理大量的游戏对象。</li><li>任务并行:ECS使用任务并行技术,使得游戏的逻辑可以在多个CPU核心上并行执行,从而提高了游戏的性能。</li><li>内存布局:ECS使用紧凑的内存布局,使得游戏对象的数据可以更快地被访问,从而提高了游戏的性能。</li></ul><h2 id="实体(Entity)"><a href="#实体(Entity)" class="headerlink" title="实体(Entity)"></a>实体(Entity)</h2><p>实体是Unity ECS中的基本概念,它是游戏对象的标识符。在Unity ECS中,实体通常只包含一个ID,用于标识游戏对象。实体本身并不包含任何数据,而是由组件来描述游戏对象的属性。</p><p>在代码中,可以通过以下方式创建实体:</p><p> <code>Entity entity = entityManager.CreateEntity()</code></p><p>其中,entityManager是实体管理器,用于创建、管理和销毁实体。创建实体后,可以通过实体管理器给实体添加组件。</p><h2 id="组件(Component)"><a href="#组件(Component)" class="headerlink" title="组件(Component)"></a>组件(Component)</h2><p>组件是Unity ECS中描述游戏对象属性的基本单元,每个组件只描述一个属性。例如,一个游戏对象可能包含位置、旋转、缩放等多个属性,每个属性对应一个组件。组件通常包含一个结构体,用于描述属性。</p><p>在代码中,可以通过以下方式添加组件:</p><p> <code>entityManager.AddComponentData(entity, new Position { Value = new float3(0, 0, 0) });</code></p><p>其中,entityManager是实体管理器,entity是要添加组件的实体,Position是组件类型,new Position { Value = new float3(0, 0, 0) }是组件的值。可以给实体添加多个组件,每个组件对应一个类型。</p><h2 id="系统(System)"><a href="#系统(System)" class="headerlink" title="系统(System)"></a>系统(System)</h2><p>系统是Unity ECS中描述游戏对象行为的基本单元,每个系统只描述一个行为。系统负责对实体和组件进行操作,例如更新位置、</p><p>下面我会给出一个完整的Unity ECS代码示例,包括Entity、Component和System三个部分。</p><p>首先是Entity部分,我们需要创建一个Entity实体,并添加需要的组件。</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> Unity.Entities;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CreateEntityExample</span> : <span class="hljs-title">MonoBehaviour</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>()</span><br> {<br> EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;<br> <br> Entity entity = entityManager.CreateEntity();<br> <br> <span class="hljs-comment">// 添加Position组件</span><br> entityManager.AddComponentData(entity, <span class="hljs-keyword">new</span> Position { Value = <span class="hljs-keyword">new</span> float3(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span> ) } );<br> <br> <span class="hljs-comment">// 添加MoveSpeed组件</span><br> entityManager.AddComponentData(entity, <span class="hljs-keyword">new</span> MoveSpeed { Value = <span class="hljs-number">1.0f</span> });<br> }<br>}```<br><br>在这个示例中,我们使用 EntityManager 类创建了一个实体,并添加了 Position 和 MoveSpeed 组件。Position 组件表示实体的位置,MoveSpeed 组件表示实体的移动速度。<br><br>接下来是Component部分,我们需要定义组件数据结构。<br><br>```C<span class="hljs-meta">#</span><br><span class="hljs-keyword">using</span> Unity.Entities;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">struct</span> Position : IComponentData<br>{<br> <span class="hljs-keyword">public</span> float3 Value;<br>}<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">struct</span> MoveSpeed : IComponentData<br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">float</span> Value;<br>}<br></code></pre></td></tr></table></figure><p>在这个示例中,我们定义了 Position 和 MoveSpeed 两个组件,它们都继承自 IComponentData 接口,表示它们是纯数据类型的组件。</p><p>最后是System部分,我们需要创建一个系统,并在其中更新实体的位置。</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> Unity.Entities;<br><span class="hljs-keyword">using</span> Unity.Transforms;<br><span class="hljs-keyword">using</span> Unity.Mathematics;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MovementSystem</span> : <span class="hljs-title">SystemBase</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnUpdate</span>()</span><br> {<br> <span class="hljs-built_in">float</span> deltaTime = Time.DeltaTime;<br> <br> Entities.ForEach((<span class="hljs-keyword">ref</span> Translation translation, <span class="hljs-keyword">in</span> MoveSpeed moveSpeed) =><br> {<br> float3 position = translation.Value;<br> position.x += moveSpeed.Value * deltaTime;<br> translation.Value = position;<br> }).ScheduleParallel();<br> }<br>}<br></code></pre></td></tr></table></figure><p><a href="https://blog.csdn.net/pengfeicfan/article/details/129374673">原文链接</a></p>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>Unity 绑定(订阅)事件方式</title>
<link href="/2024/07/24/Unity%20Coroutine%E5%8D%8F%E7%A8%8B/"/>
<url>/2024/07/24/Unity%20Coroutine%E5%8D%8F%E7%A8%8B/</url>
<content type="html"><![CDATA[<p><a href="https://docs.unity3d.com/cn/2021.1/Manual/Coroutines.html">协程 - Unity 手册 (unity3d.com)</a></p><p>协程就是一种特殊的函数,它可以主动的请求暂停自身并提交一个唤醒条件,Unity会在唤醒条件满足的时候去重新唤醒协程。<br>当开始一个协程后,当前线程会先完成协程(或协程主动跳出),然后回到主线程。</p><table><thead><tr><th></th><th><strong>协程</strong></th><th><strong>多线程</strong></th></tr></thead><tbody><tr><td><strong>切换时机</strong></td><td>自定</td><td>CPU时间片为单位的系统调度</td></tr><tr><td><strong>CUP核心</strong></td><td>与主线程在同一核心</td><td>根据操作系统调度不同</td></tr><tr><td><strong>对主线程的影响</strong></td><td>卡顿会影响主线程</td><td>卡死都不影响主线程</td></tr><tr><td><strong>线程同步影响</strong></td><td>不存在线程同步问题</td><td>需要注意线程同步问题</td></tr><tr><td><strong>线程开销</strong></td><td>不存在线程开销</td><td>存在线程创建、销毁、切换的开销</td></tr><tr><td><strong>书写方式</strong></td><td>与普通函数一致</td><td>回调函数</td></tr></tbody></table><table><thead><tr><th><strong>yield语句</strong></th><th><strong>功能</strong></th></tr></thead><tbody><tr><td>yield return null;</td><td>下一帧再执行后续代码</td></tr><tr><td>yield return 0;</td><td>下一帧再执行后续代码</td></tr><tr><td>yield return 6(任意数字);</td><td>下一帧再执行后续代码</td></tr><tr><td>yield break;</td><td>直接结束该协程的后续操作</td></tr><tr><td>yield return asyncOperation;</td><td>等异步操作结束后再执行后续代码</td></tr><tr><td>yield return StartCoroution(其他协程);</td><td>调用其他协程后再执行后续代码</td></tr><tr><td>yield return WWW();</td><td>等待WWW操作完成后再执行后续代码</td></tr><tr><td>yield return new WaitForEndOfFrame();</td><td>等待帧结束,等待所有摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行</td></tr><tr><td>yield return new WaitForSeconds(0.3f);</td><td>等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.TimeScale的影响)</td></tr><tr><td>yield return new WaitForSecondsRealtime(0.3f);</td><td>等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.TimeScale的影响)</td></tr><tr><td>yield return WaitForFixedUpdate</td><td>等待下一次FixedUpdate开始时再执行后续代码</td></tr><tr><td>yield return new WaitUntil();</td><td>将协同程序执行直到当输入的参数(或者委托)为true的时候</td></tr><tr><td>yield return new WaitWhile();</td><td>将协同程序执行直到当输入的参数(或者委托)为false的时候</td></tr><tr><td>当某一个脚本中的协程在执行过程中,如果我们将该脚本的enable设置为false,协程不会停止(因为它是基于C#中的IEnumerator)。只有将挂载该脚本的物体设置为SetActive(false)时才会停止。</td><td></td></tr></tbody></table><p>Unity在调用StartCoroutine()后不会等待协程中的内容返回,会立即执行后续代码。</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-function">IEnumerator <span class="hljs-title">CaculateResult</span>()</span><br>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-built_in">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10000</span>; i++)<br> {<br> <span class="hljs-comment">//内部循环计算</span><br> <span class="hljs-comment">//在这里的yield会让改内部循环计算每帧执行一次,而不会等待10000次循环结束后再跳出</span><br> <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <span class="hljs-comment">//如果取消内部的yield操作,仅在for循环外边写yield操作,则会执行完10000次循环后再结束,相当于直接调用了一个函数,而非协程。</span><br> <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs C#"> <span class="hljs-function">IEnumerator <span class="hljs-title">UpdateTick</span>()</span><br> {<br> <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>)<br> {<br> <span class="hljs-keyword">if</span> (GameRuning)<br> {<br> AddTick();<br> <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; <span class="hljs-comment">//在这里的yield操作会使内部循环每帧执行一次,而不会等待循环完成后再跳出</span><br> }<br> }<br> <span class="hljs-comment">//yield return null; //会等待while(true)循环执行完后再结束,相当于直接调用了一个函数而非协程</span><br> }<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>Winform和WPF</title>
<link href="/2024/07/24/Winform%E5%92%8CWPF/"/>
<url>/2024/07/24/Winform%E5%92%8CWPF/</url>
<content type="html"><![CDATA[<h2 id="01-设计理念不同"><a href="#01-设计理念不同" class="headerlink" title="01 设计理念不同"></a><strong>01</strong> 设计理念不同</h2><p>WinForm是2001年推出的界面应用开发框架,采用的是窗体和控件模型,以事件驱动的开发模式,并且提供了丰富控件库,方便开发者开发应用程序。</p><p>WPF是2006年推出的界面应用开发UI框架,引入了一种全新的界面开发模型,使用XAML来定义界面,允许开发者通过声明的方式来定义界面的外观和行为。</p><h2 id="02-UI设计与布局不同"><a href="#02-UI设计与布局不同" class="headerlink" title="02 UI设计与布局不同"></a><strong>02</strong> UI设计与布局不同</h2><p>WinForm是基于像素级别的布局模式,需要开发者手动去设置控件的位置和大小,这种方式对于一些简单界面设计比较直接方便,但面对复杂的布局时就要需要花费更多的时间和精力。</p><p>WPF基于向量的布局模式,可通过堆叠、网格、对齐等布局元素等元素来调整控件的位置和大小,这种方式更加灵活高效,可以轻松实现复杂的布局,可提升开发效率。</p><h2 id="03-渲染机制与效果不同"><a href="#03-渲染机制与效果不同" class="headerlink" title="03 渲染机制与效果不同"></a><strong>03</strong> 渲染机制与效果不同</h2><p>WinForm采用的是GDI+绘制,WPF采用的是DirectX 渲染绘制。WPF可以很轻松的设计界面的外观和行为,并且提供了丰富的控件库,也方便自定义扩展,WPF还支持3D和动画效果,使得界面效果更加美观与生动。</p><p>WinForm自定义样式就比较麻烦,往往需要借助第三方控件库,或者自己自定义绘制,而且工作量非常巨大。</p><h2 id="04-数据绑定不同"><a href="#04-数据绑定不同" class="headerlink" title="04 数据绑定不同"></a><strong>04</strong> 数据绑定不同</h2><p>WinForm数据绑定方式比较简单,通过设定数据源、元素的属性等方式来设定,不方便扩展,并且需要开发者手动编写代码来设定。</p><p>WPF采用的是MVVM模式,将界面与数据模型很好的分开,并且实现数据自动更新与同步,不需要开发者手动设定,降低了界面设计与业务逻辑的耦合。这种模式,便于设计人员与开发人员同步进行,方便后续的维护和开发。</p><h2 id="05-性能不同"><a href="#05-性能不同" class="headerlink" title="05 性能不同"></a><strong>05</strong> 性能不同</h2><p>WPF采用了复杂图像渲染引擎,提供了更多动画效果,通常情况下WinForm性能比WPF好一点,占用的资源和内存往往也更低。</p><p>WPF是基于矢量的图形渲染方式,可以更好地利用多核CPU进行渲染,从而提高渲染速度。</p><h2 id="06-学习成本不同"><a href="#06-学习成本不同" class="headerlink" title="06 学习成本不同"></a><strong>06</strong> 学习成本不同</h2><p>从学习成本看,WinForm可能更容易上手,因为它的概念和设计更直观,需要的编程技能也更少。WPF的学习曲线相对较陡峭,需要更多的学习和实践。</p><h2 id="07-社区流行与未来发展"><a href="#07-社区流行与未来发展" class="headerlink" title="07 社区流行与未来发展"></a><strong>07</strong> 社区流行与未来发展</h2><p>WPF比WinForm更晚推出,说明微软官方发现WinForm一些不足,从而提出全新的开发模式,而且从Github开源项目数量分析看,WPF相关的开源项目、UI控件、解决方案等,都比WinForm丰富很多。</p><p>虽然说微软一直在推动WPF发展与更新,但是目前还未能全部替换WinForm,两者也都在保持发展和更新中。</p><h2 id="08-项目类型与选择"><a href="#08-项目类型与选择" class="headerlink" title="08 项目类型与选择"></a><strong>08</strong> 项目类型与选择</h2><p>对于项目开发中,选择哪个技术,这需要根据项目的需求来具体分析。</p><p>对于一些界面简洁、更注重功能开发的项目,可以选择WinForm,从而达到高效开发的效果。</p><p>对于一些要求实现现代化的、具有高级图形效果和交互体验的用户界面的项目,可以选择WPF,可以更好的把界面与业务逻辑分开,也方便界面设计人员与开发人员协作同步进行。</p>]]></content>
<tags>
<tag>桌面开发</tag>
</tags>
</entry>
<entry>
<title>异步</title>
<link href="/2024/07/24/%E5%BC%82%E6%AD%A5/"/>
<url>/2024/07/24/%E5%BC%82%E6%AD%A5/</url>
<content type="html"><![CDATA[<p>.NET C# 异步编程是为了编写高效、响应迅速的应用程序而设计的编程模式。它主要通过 <code>async</code> 和 <code>await</code> 关键字来实现异步操作,使代码更加简洁和可读。下面是对 C# 异步编程的一些关键概念和技术的详细解释:</p><h3 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h3><ol><li><p><strong>异步方法</strong>:</p><ul><li>异步方法使用 <code>async</code> 修饰符定义,返回类型通常是 <code>Task</code>、<code>Task<T></code> 或 <code>void</code>(仅限于事件处理程序)。</li><li>异步方法可以包含 <code>await</code> 表达式,用于暂停方法执行,直到异步操作完成。</li></ul></li><li><p><strong><code>await</code> 表达式</strong>:</p><ul><li><code>await</code> 用于暂停异步方法的执行,等待异步操作完成,然后继续执行方法中的后续代码。</li><li><code>await</code> 可以用于任何返回 <code>Task</code> 或 <code>Task<T></code> 的方法。</li></ul></li></ol><h3 id="示例代码"><a href="#示例代码" class="headerlink" title="示例代码"></a>示例代码</h3><h4 id="异步方法示例"><a href="#异步方法示例" class="headerlink" title="异步方法示例"></a>异步方法示例</h4><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task<<span class="hljs-built_in">int</span>> <span class="hljs-title">GetDataAsync</span>()</span><br>{<br> <span class="hljs-comment">// 模拟异步操作,例如从网络获取数据</span><br> <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">1000</span>); <span class="hljs-comment">// 1秒的延迟,模拟异步操作</span><br> <span class="hljs-keyword">return</span> <span class="hljs-number">42</span>;<br>}<br></code></pre></td></tr></table></figure><h4 id="使用-await-调用异步方法"><a href="#使用-await-调用异步方法" class="headerlink" title="使用 await 调用异步方法"></a>使用 <code>await</code> 调用异步方法</h4><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">ProcessDataAsync</span>()</span><br>{<br> <span class="hljs-built_in">int</span> result = <span class="hljs-keyword">await</span> GetDataAsync();<br> Console.WriteLine(<span class="hljs-string">$"Result: <span class="hljs-subst">{result}</span>"</span>);<br>}<br></code></pre></td></tr></table></figure><h3 id="异步编程的好处"><a href="#异步编程的好处" class="headerlink" title="异步编程的好处"></a>异步编程的好处</h3><ol><li><p><strong>提高应用程序响应性</strong>:</p><ul><li>异步操作可以避免阻塞主线程,特别是在 GUI 应用程序中,避免冻结界面。</li></ul></li><li><p><strong>更好的资源利用</strong>:</p><ul><li>异步编程可以更高效地利用系统资源,允许 CPU 在等待 I/O 操作完成时执行其他任务。</li></ul></li><li><p><strong>简化异步代码</strong>:</p><ul><li>使用 <code>async</code> 和 <code>await</code> 关键字,可以让异步代码看起来像同步代码,更容易编写和维护。</li></ul></li></ol><h3 id="常用的异步方法和模式"><a href="#常用的异步方法和模式" class="headerlink" title="常用的异步方法和模式"></a>常用的异步方法和模式</h3><h4 id="异步-I-O-操作"><a href="#异步-I-O-操作" class="headerlink" title="异步 I/O 操作"></a>异步 I/O 操作</h4><p>在 .NET 中,许多 I/O 操作都支持异步方法。例如,读取文件内容可以使用 <code>StreamReader</code> 的 <code>ReadToEndAsync</code> 方法:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task<<span class="hljs-built_in">string</span>> <span class="hljs-title">ReadFileAsync</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> filePath</span>)</span><br>{<br> <span class="hljs-keyword">using</span> (StreamReader reader = <span class="hljs-keyword">new</span> StreamReader(filePath))<br> {<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> reader.ReadToEndAsync();<br> }<br>}<br></code></pre></td></tr></table></figure><h4 id="异步-HTTP-请求"><a href="#异步-HTTP-请求" class="headerlink" title="异步 HTTP 请求"></a>异步 HTTP 请求</h4><p>通过 <code>HttpClient</code> 类,可以方便地进行异步 HTTP 请求:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task<<span class="hljs-built_in">string</span>> <span class="hljs-title">FetchDataFromApiAsync</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> url</span>)</span><br>{<br> <span class="hljs-keyword">using</span> (HttpClient client = <span class="hljs-keyword">new</span> HttpClient())<br> {<br> HttpResponseMessage response = <span class="hljs-keyword">await</span> client.GetAsync(url);<br> response.EnsureSuccessStatusCode();<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> response.Content.ReadAsStringAsync();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="并行执行多个异步操作"><a href="#并行执行多个异步操作" class="headerlink" title="并行执行多个异步操作"></a>并行执行多个异步操作</h3><p>可以使用 <code>Task.WhenAll</code> 方法并行执行多个异步操作:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">ProcessMultipleTasksAsync</span>()</span><br>{<br> Task<<span class="hljs-built_in">int</span>> task1 = GetDataAsync();<br> Task<<span class="hljs-built_in">string</span>> task2 = ReadFileAsync(<span class="hljs-string">"example.txt"</span>);<br><br> <span class="hljs-keyword">await</span> Task.WhenAll(task1, task2);<br><br> <span class="hljs-built_in">int</span> result1 = <span class="hljs-keyword">await</span> task1;<br> <span class="hljs-built_in">string</span> result2 = <span class="hljs-keyword">await</span> task2;<br><br> Console.WriteLine(<span class="hljs-string">$"Result1: <span class="hljs-subst">{result1}</span>, Result2: <span class="hljs-subst">{result2}</span>"</span>);<br>}<br></code></pre></td></tr></table></figure><h3 id="异常处理"><a href="#异常处理" class="headerlink" title="异常处理"></a>异常处理</h3><p>异步方法中的异常可以使用 <code>try-catch</code> 进行处理:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">ProcessDataWithErrorHandlingAsync</span>()</span><br>{<br> <span class="hljs-keyword">try</span><br> {<br> <span class="hljs-built_in">int</span> result = <span class="hljs-keyword">await</span> GetDataAsync();<br> Console.WriteLine(<span class="hljs-string">$"Result: <span class="hljs-subst">{result}</span>"</span>);<br> }<br> <span class="hljs-keyword">catch</span> (Exception ex)<br> {<br> Console.WriteLine(<span class="hljs-string">$"Error: <span class="hljs-subst">{ex.Message}</span>"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>字典Dictionary</title>
<link href="/2024/07/24/%E5%AD%97%E5%85%B8Dictionary/"/>
<url>/2024/07/24/%E5%AD%97%E5%85%B8Dictionary/</url>
<content type="html"><![CDATA[<p>在 C# 中使用 <code>Dictionary<TKey, TValue></code> 时,需要注意以下几点:</p><ol><li><p><strong>键的唯一性</strong>:</p><ul><li>字典中的每个键必须是唯一的。如果尝试添加一个已经存在的键,会抛出 <code>ArgumentException</code>。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">var</span> dict = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">int</span>, <span class="hljs-built_in">string</span>>();<br>dict.Add(<span class="hljs-number">1</span>, <span class="hljs-string">"value1"</span>);<br>dict.Add(<span class="hljs-number">1</span>, <span class="hljs-string">"value2"</span>); <span class="hljs-comment">// 抛出 ArgumentException</span><br></code></pre></td></tr></table></figure></li></ul></li><li><p><strong>键的哈希码和相等性</strong>:</p><ul><li>键的类型必须正确实现 <code>GetHashCode</code> 和 <code>Equals</code> 方法。如果键的类型是一个自定义类,确保正确实现这两个方法,以便字典能够正确区分键。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Key</span><br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-built_in">bool</span> <span class="hljs-title">Equals</span>(<span class="hljs-params"><span class="hljs-built_in">object</span> obj</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (obj <span class="hljs-keyword">is</span> Key key)<br> <span class="hljs-keyword">return</span> Id == key.Id;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-built_in">int</span> <span class="hljs-title">GetHashCode</span>()</span><br> {<br> <span class="hljs-keyword">return</span> Id.GetHashCode();<br> }<br>}<br></code></pre></td></tr></table></figure></li></ul></li><li><p><strong>性能考虑</strong>:</p><ul><li>字典查找、添加和删除操作的时间复杂度平均为 O(1),但在哈希冲突较多的情况下可能退化到 O(n)。选择合适的键类型和哈希函数以减少冲突。</li></ul></li><li><p><strong>访问不存在的键</strong>:</p><ul><li>直接访问一个不存在的键会抛出 <code>KeyNotFoundException</code>。可以使用 <code>TryGetValue</code> 方法避免异常。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">if</span> (dict.TryGetValue(<span class="hljs-number">2</span>, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> <span class="hljs-keyword">value</span>))<br>{<br> Console.WriteLine(<span class="hljs-keyword">value</span>);<br>}<br><span class="hljs-keyword">else</span><br>{<br> Console.WriteLine(<span class="hljs-string">"Key not found"</span>);<br>}<br></code></pre></td></tr></table></figure></li></ul></li><li><p><strong>初始化容量</strong>:</p><ul><li>如果知道字典的大致大小,可以在初始化时指定容量,减少扩容带来的性能开销。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">var</span> dict = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">int</span>, <span class="hljs-built_in">string</span>>(capacity: <span class="hljs-number">100</span>);<br></code></pre></td></tr></table></figure></li></ul></li><li><p><strong>线程安全</strong>:</p><ul><li><code>Dictionary<TKey, TValue></code> 本身不是线程安全的。如果在多线程环境中使用,请使用 <code>ConcurrentDictionary<TKey, TValue></code> 或手动实现同步机制。</li></ul></li><li><p><strong>迭代和修改</strong>:</p><ul><li>在迭代字典时修改字典会抛出 <code>InvalidOperationException</code>。如果需要修改,可以先收集要修改的键值对,然后在迭代完成后再进行修改。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> dict.Keys.ToList())<br>{<br> <span class="hljs-keyword">if</span> (key == <span class="hljs-number">1</span>)<br> {<br> dict[key] = <span class="hljs-string">"newValue"</span>;<br> }<br>}<br></code></pre></td></tr></table></figure></li></ul></li><li><p><strong>序列化</strong>:</p><ul><li>字典可以被序列化,但要确保键和值的类型都支持序列化。常用的 JSON 序列化库如 <code>JsonConvert</code> 和 <code>System.Text.Json</code> 都支持字典。<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">var</span> json = JsonConvert.SerializeObject(dict);<br><span class="hljs-keyword">var</span> deserializedDict = JsonConvert.DeserializeObject<Dictionary<<span class="hljs-built_in">int</span>, <span class="hljs-built_in">string</span>>>(json);<br></code></pre></td></tr></table></figure></li></ul></li></ol><h3 id="示例代码"><a href="#示例代码" class="headerlink" title="示例代码"></a>示例代码</h3><p>这段示例代码展示了如何正确使用字典以及注意事项。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">using</span> System;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>()</span><br> {<br> <span class="hljs-keyword">var</span> dict = <span class="hljs-keyword">new</span> Dictionary<<span class="hljs-built_in">int</span>, <span class="hljs-built_in">string</span>>();<br><br> <span class="hljs-comment">// 添加元素</span><br> dict.Add(<span class="hljs-number">1</span>, <span class="hljs-string">"value1"</span>);<br> dict[<span class="hljs-number">2</span>] = <span class="hljs-string">"value2"</span>; <span class="hljs-comment">// 另一种添加方式</span><br><br> <span class="hljs-comment">// 访问元素</span><br> <span class="hljs-keyword">if</span> (dict.TryGetValue(<span class="hljs-number">1</span>, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> <span class="hljs-keyword">value</span>))<br> {<br> Console.WriteLine(<span class="hljs-keyword">value</span>); <span class="hljs-comment">// 输出: value1</span><br> }<br><br> <span class="hljs-comment">// 遍历字典</span><br> <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> kvp <span class="hljs-keyword">in</span> dict)<br> {<br> Console.WriteLine(<span class="hljs-string">$"Key: <span class="hljs-subst">{kvp.Key}</span>, Value: <span class="hljs-subst">{kvp.Value}</span>"</span>);<br> }<br><br> <span class="hljs-comment">// 删除元素</span><br> dict.Remove(<span class="hljs-number">1</span>);<br><br> <span class="hljs-comment">// 检查键是否存在</span><br> <span class="hljs-keyword">if</span> (!dict.ContainsKey(<span class="hljs-number">1</span>))<br> {<br> Console.WriteLine(<span class="hljs-string">"Key 1 not found"</span>);<br> }<br><br> <span class="hljs-comment">// 键的自定义类</span><br> <span class="hljs-keyword">var</span> customDict = <span class="hljs-keyword">new</span> Dictionary<Key, <span class="hljs-built_in">string</span>>();<br> <span class="hljs-keyword">var</span> key1 = <span class="hljs-keyword">new</span> Key { Id = <span class="hljs-number">1</span> };<br> customDict[key1] = <span class="hljs-string">"customValue1"</span>;<br> Console.WriteLine(customDict[key1]); <span class="hljs-comment">// 输出: customValue1</span><br> }<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Key</span><br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-built_in">bool</span> <span class="hljs-title">Equals</span>(<span class="hljs-params"><span class="hljs-built_in">object</span> obj</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (obj <span class="hljs-keyword">is</span> Key key)<br> <span class="hljs-keyword">return</span> Id == key.Id;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-built_in">int</span> <span class="hljs-title">GetHashCode</span>()</span><br> {<br> <span class="hljs-keyword">return</span> Id.GetHashCode();<br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>常用目录</title>
<link href="/2024/07/24/%E5%B8%B8%E7%94%A8%E7%9B%AE%E5%BD%95/"/>
<url>/2024/07/24/%E5%B8%B8%E7%94%A8%E7%9B%AE%E5%BD%95/</url>
<content type="html"><![CDATA[<h2 id="一些常用目录"><a href="#一些常用目录" class="headerlink" title="一些常用目录"></a>一些常用目录</h2><ul><li><strong>当前工作目录</strong>:程序启动时默认的工作目录。可以通过 <code>Directory.GetCurrentDirectory()</code> 方法获取。<br>输出:<code>D:\桌面\ConsoleApp1</code></li><li><strong>应用程序目录</strong>:包含可执行文件的目录。可以通过 <code>AppDomain.CurrentDomain.BaseDirectory</code> 属性获取。<br>输出:<code>D:\桌面\ConsoleApp1\bin\Debug\net6.0\</code></li><li><strong>特定文件路径</strong>:需要读取或写入的具体文件的路径,如配置文件、日志文件等。<br>输出:</li><li><strong>用户文档目录</strong>:用户的文档目录,通常用于保存用户数据、设置文件等。可以通过 <code>Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)</code> 方法获取。<br>输出:<code>D:\文档</code></li><li><strong>系统临时目录</strong>:用于存储临时文件和缓存数据。可以通过 <code>Path.GetTempPath()</code> 方法获取。<br>输出:</li><li><strong>系统目录</strong>:包含系统文件的目录,如系统 DLL、系统文件等。可以通过 <code>Environment.SystemDirectory</code> 属性获取。<br>输出:</li><li><strong>用户应用程序数据目录</strong>:用于存储应用程序数据的目录,通常用于保存应用程序设置、日志文件等。可以通过 <code>Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)</code> 方法获取。<br>输出:<code>C:\Users\48782\AppData\Roaming</code></li><li><strong>公共文档目录</strong>:所有用户都可以访问的文档目录,通常用于存储公共数据、共享设置文件等。可以通过 <code>Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)</code> 方法获取。<br>输出:<code>C:\Users\Public\Documents</code></li><li><strong>程序集目录</strong>:包含程序集文件的目录,通常用于加载程序集或查找程序集文件。可以通过 <code>Assembly.GetExecutingAssembly().Location</code> 获取当前程序集所在的完整路径。<br>输出:<code>D:\桌面\ConsoleApp1\bin\Debug\net6.0\ConsoleApp1.dll</code></li></ul><h2 id="Path-Combine-自动合成字符串为文件路径"><a href="#Path-Combine-自动合成字符串为文件路径" class="headerlink" title="Path.Combine() 自动合成字符串为文件路径"></a>Path.Combine() 自动合成字符串为文件路径</h2><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">programe</span><br>{<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">main</span>()</span><br>{<br><span class="hljs-built_in">string</span> filepath = Path.Combine(<span class="hljs-string">"bin"</span>,<span class="hljs-string">"data"</span>,<span class="hljs-string">"data.ini"</span>);<br>Debug.WriteLine(filepath);<br>}<br>}<br><br><span class="hljs-comment">// 输出:D:\桌面\ConsoleApp1\bin\data\data.ini</span><br><br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>扩展和重写方法</title>
<link href="/2024/07/24/%E6%89%A9%E5%B1%95%E5%92%8C%E9%87%8D%E5%86%99%E6%96%B9%E6%B3%95/"/>
<url>/2024/07/24/%E6%89%A9%E5%B1%95%E5%92%8C%E9%87%8D%E5%86%99%E6%96%B9%E6%B3%95/</url>
<content type="html"><![CDATA[<p><code>virtual</code> 虚方法:在基类中提供一个默认实现,但允许子类选择性的重写它<br><code>abstract</code> 抽象方法:基类中不能有具体实现,子类必须实现</p><blockquote><p>虚拟成员或抽象成员不能是私有的,不能使用private关键字(编辑器会提示的,所以不必担心)</p></blockquote><h2 id="使用-virtual-和-abstract-关键字"><a href="#使用-virtual-和-abstract-关键字" class="headerlink" title="使用 virtual 和 abstract 关键字"></a>使用 <code>virtual</code> 和 <code>abstract</code> 关键字</h2><p>当你提供一个方法的默认实现,并允许子类选择性地重写它时,可以使用 <code>virtual</code> 关键字。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span><br>{<br> <span class="hljs-comment">// 一个虚方法,子类可以选择性地重写它</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoWork</span>()</span><br> {<br> Console.WriteLine(<span class="hljs-string">"BaseClass DoWork"</span>);<br> }<br><br> <span class="hljs-comment">// 其他抽象方法或属性,必须在子类中实现</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoSpecificWork</span>()</span>;<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span><br>{<br> <span class="hljs-comment">// 重写虚方法</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoWork</span>()</span><br> {<br> Console.WriteLine(<span class="hljs-string">"DerivedClass DoWork"</span>);<br> }<br><br> <span class="hljs-comment">// 实现抽象方法</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoSpecificWork</span>()</span><br> {<br> Console.WriteLine(<span class="hljs-string">"DerivedClass DoSpecificWork"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="派生类重写虚方法的同时,实现基类的虚方法"><a href="#派生类重写虚方法的同时,实现基类的虚方法" class="headerlink" title="派生类重写虚方法的同时,实现基类的虚方法"></a>派生类重写虚方法的同时,实现基类的虚方法</h2><p>在 C# 中,当子类重写基类中的虚方法时,基类中的虚方法实现不会自动执行。也就是说,除非在重写的子类方法中显式调用基类的方法,基类的实现将不会执行。</p><p>你可以使用 <code>base</code> 关键字在重写的方法中显式调用基类的虚方法。这样可以在子类中扩展或修改基类的方法逻辑。</p><p>下面是一个示例,展示了如何在子类中重写基类的虚方法,并选择性地调用基类的实现:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">using</span> System;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span><br>{<br> <span class="hljs-comment">// 一个虚方法,子类可以选择性地重写它</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoWork</span>()</span><br> {<br> Console.WriteLine(<span class="hljs-string">"BaseClass DoWork"</span>);<br> }<br><br> <span class="hljs-comment">// 另一个抽象方法,子类必须实现它</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoSpecificWork</span>()</span>;<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span><br>{<br> <span class="hljs-comment">// 重写虚方法</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoWork</span>()</span><br> {<br> <span class="hljs-comment">// 显式调用基类的虚方法实现</span><br> <span class="hljs-keyword">base</span>.DoWork();<br><br> <span class="hljs-comment">// 扩展或修改方法逻辑</span><br> Console.WriteLine(<span class="hljs-string">"DerivedClass DoWork"</span>);<br> }<br><br> <span class="hljs-comment">// 实现抽象方法</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoSpecificWork</span>()</span><br> {<br> Console.WriteLine(<span class="hljs-string">"DerivedClass DoSpecificWork"</span>);<br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>()</span><br> {<br> BaseClass obj = <span class="hljs-keyword">new</span> DerivedClass();<br> obj.DoWork(); <span class="hljs-comment">// 将输出: BaseClass DoWork \n DerivedClass DoWork</span><br> obj.DoSpecificWork(); <span class="hljs-comment">// 将输出: DerivedClass DoSpecificWork</span><br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>关于EventArgs</title>
<link href="/2024/07/24/%E5%85%B3%E4%BA%8E%20EventArgs/"/>
<url>/2024/07/24/%E5%85%B3%E4%BA%8E%20EventArgs/</url>
<content type="html"><![CDATA[<h2 id="什么是EventArgs"><a href="#什么是EventArgs" class="headerlink" title="什么是EventArgs?"></a>什么是EventArgs?</h2><p>在C#中,<code>EventArgs</code>是一个基类,用于封装与事件相关的数据。它包含一个 <code>EventArgs</code>对象,该对象包含与事件相关的任何信息。当某个事件被触发时,可以向该事件添加一个事件处理器,并将与事件相关的数据传递给该处理器。</p><p><code>EventArgs</code>类通常包含一个名为 <code>e</code>的实例变量,该变量包含与事件相关的数据。例如,当鼠标在窗口上移动时,会触发一个 <code>MouseMove</code>事件。这个事件可以有一个参数,该参数是一个 <code>MouseEventArgs</code>对象,该对象包含有关鼠标移动的信息,如鼠标的位置和鼠标按钮的状态。</p><p>使用 <code>EventArgs</code>类的好处是,它提供了一种通用的方式来传递事件相关的数据。这意味着开发人员可以编写一个事件处理器,该处理器可以处理多种不同类型的事件,而无需关心事件的特定数据。这使得代码更加模块化和可重用。</p><h2 id="什么时候使用-EventArgs类?"><a href="#什么时候使用-EventArgs类?" class="headerlink" title="什么时候使用 EventArgs类?"></a>什么时候使用 <code>EventArgs</code>类?</h2><p>当您需要向事件添加一个事件处理器,并且需要将与事件相关的数据传递给该处理器时,就可以使用 <code>EventArgs</code>类。例如,如果您正在编写一个图形用户界面(GUI)应用程序,并且需要处理鼠标和键盘事件,那么您可以使用 <code>EventArgs</code>类来传递与这些事件相关的数据。</p><p>以下是一个简单的示例,演示了如何使用 <code>EventArgs</code>类来处理一个自定义事件:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span><br>{<br> <span class="hljs-comment">// 定义一个自定义事件</span><br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">event</span> EventHandler<MyEventArgs> MyEvent;<br><br> <span class="hljs-comment">// 触发自定义事件的方法</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DoSomething</span>()</span><br> {<br> <span class="hljs-comment">// 创建 MyEventArgs 实例并设置相关属性</span><br> MyEventArgs args = <span class="hljs-keyword">new</span> MyEventArgs();<br> args.Message = <span class="hljs-string">"Something happened!"</span>;<br><br> <span class="hljs-comment">// 触发事件并传递 MyEventArgs 实例作为参数</span><br> MyEvent?.Invoke(<span class="hljs-keyword">this</span>, args);<br> }<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MyEventArgs</span> : <span class="hljs-title">EventArgs</span><br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Message { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br>}<br></code></pre></td></tr></table></figure><p>在上面的示例中,我们定义了一个名为 <code>MyEvent</code>的自定义事件,它使用了一个自定义的 <code>MyEventArgs</code>类作为参数。当调用 <code>DoSomething</code>方法时,它会创建一个新的 <code>MyEventArgs</code>实例,设置其属性,并触发事件。任何订阅了该事件的处理器都可以访问传递的 <code>MyEventArgs</code>实例中的数据。</p>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>访问级别关键字</title>
<link href="/2024/07/24/%E8%AE%BF%E9%97%AE%E7%BA%A7%E5%88%AB%E5%85%B3%E9%94%AE%E5%AD%97/"/>
<url>/2024/07/24/%E8%AE%BF%E9%97%AE%E7%BA%A7%E5%88%AB%E5%85%B3%E9%94%AE%E5%AD%97/</url>
<content type="html"><![CDATA[<p>类的构造函数使用不同的访问级别关键字(如 <code>protected</code>、<code>public</code>、<code>private</code> 等)有不同的含义和用途:</p><h2 id="public"><a href="#public" class="headerlink" title="public"></a><code>public</code></h2><ul><li><strong>用途</strong>: 构造函数可以被任何代码访问。</li><li><strong>适用场景</strong>: 用于实例化类的对象时没有任何限制。</li></ul><h2 id="private"><a href="#private" class="headerlink" title="private"></a><code>private</code></h2><ul><li><strong>用途</strong>: 构造函数只能在类的内部被访问。</li><li><strong>适用场景</strong>: 用于实现单例模式或静态类,防止类被外部实例化。</li></ul><h2 id="protected"><a href="#protected" class="headerlink" title="protected"></a><code>protected</code></h2><ul><li><strong>用途</strong>: 构造函数只能在类的内部或其派生类中被访问。</li><li><strong>适用场景</strong>: 用于基类,允许派生类继承并实例化,但防止基类本身被直接实例化。</li></ul><h2 id="internal"><a href="#internal" class="headerlink" title="internal"></a><code>internal</code></h2><ul><li><strong>用途</strong>: 构造函数只能在同一程序集内被访问。</li><li><strong>适用场景</strong>: 控制类实例化的范围,通常用于库和框架内部。</li></ul><h2 id="Partial-不是用来控制访问权限的,而是用于定义分部类。"><a href="#Partial-不是用来控制访问权限的,而是用于定义分部类。" class="headerlink" title="Partial 不是用来控制访问权限的,而是用于定义分部类。"></a><code>Partial</code> 不是用来控制访问权限的,而是用于定义分部类。</h2><ul><li>用途:<ul><li>允许将一个类、结构或接口定义分散到多个文件中。</li><li>常用于与自动生成的代码配合,如Windows Forms或WPF的设计器代码。</li></ul></li><li>适用场景:<ul><li><strong>代码生成工具</strong>: 当一部分代码由工具自动生成(如设计器代码),而另一部分需要手动编写时,可以使用 <code>partial</code>关键字来保持代码的清晰和可维护性。</li><li><strong>大型类拆分</strong>: 对于非常大的类,将其分割成几个部分,每个部分放在单独的文件中,便于管理和团队协作。</li></ul></li></ul>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>MVVM</title>
<link href="/2024/07/24/MVVM/"/>
<url>/2024/07/24/MVVM/</url>
<content type="html"><![CDATA[<p>在WPF框架中使用MVVM(Model-View-ViewModel)设计模式来构建一个显示不同地区时间的世界时钟应用,我们可以这样定义M、V、VM的职责:</p><h2 id="Model-模型"><a href="#Model-模型" class="headerlink" title="Model (模型)"></a>Model (模型)</h2><p>模型层负责处理数据和业务逻辑。在这个场景下,模型可能包括:</p><ul><li><code>TimeZoneInfo</code> 对象或自定义的时区类,用于存储时区信息和计算时间偏移。</li><li>数据访问逻辑,如从系统或网络获取时区列表和当前时间。</li><li>可能还包括一些数据转换逻辑,例如将UTC时间转换为特定时区的时间。</li></ul><h2 id="ViewModel-视图模型"><a href="#ViewModel-视图模型" class="headerlink" title="ViewModel (视图模型)"></a>ViewModel (视图模型)</h2><p>视图模型作为模型和视图之间的桥梁,它:</p><ul><li>暴露数据给视图进行绑定,例如每个时钟的显示时间和时区名称。</li><li>包含命令,用于响应用户交互,如添加新的时钟或更改时区。</li><li>跟踪和更新时钟的时间,可能通过定时器或其他机制定期调用。</li><li>实现INotifyPropertyChanged接口,以便当数据改变时通知视图更新。</li></ul><h2 id="View-视图"><a href="#View-视图" class="headerlink" title="View (视图)"></a>View (视图)</h2><p>视图负责展示数据和接收用户输入,它:</p><ul><li>使用XAML定义界面布局,包括时钟的布局和样式。</li><li>绑定到ViewModel提供的属性和命令,如时钟的时间和时区选择命令。</li><li>可能会包含一些交互元素,如按钮来添加或删除时钟,以及下拉菜单来选择时区。</li></ul><h2 id="下面是一个简化的示例结构:"><a href="#下面是一个简化的示例结构:" class="headerlink" title="下面是一个简化的示例结构:"></a>下面是一个简化的示例结构:</h2><h3 id="Model"><a href="#Model" class="headerlink" title="Model"></a>Model</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TimezoneData</span> <br>{ <br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } <br><span class="hljs-keyword">public</span> TimeSpan Offset { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } <br>}<br></code></pre></td></tr></table></figure><h3 id="ViewModel"><a href="#ViewModel" class="headerlink" title="ViewModel"></a>ViewModel</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WorldClockViewModel</span> : <span class="hljs-title">INotifyPropertyChanged</span> <br>{ <br><span class="hljs-keyword">private</span> ObservableCollection<TimezoneData> _timezones; <br><span class="hljs-keyword">public</span> ObservableCollection<TimezoneData> Timezones <br>{ <br><span class="hljs-keyword">get</span> => _timezones; <br><span class="hljs-keyword">set</span> <br>{ <br>_timezones = <span class="hljs-keyword">value</span>; <br>OnPropertyChanged(<span class="hljs-keyword">nameof</span>(Timezones)); <br>} <br>} <br><span class="hljs-comment">// 假设有一个方法来更新时钟的时间 </span><br><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">UpdateClocks</span>()</span> <br>{ <br><span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> timezone <span class="hljs-keyword">in</span> Timezones) <br>{ <br>timezone.Time = CalculateLocalTime(timezone.Offset); <br>} <br>} <br><span class="hljs-comment">// 其他属性和命令... </span><br>}<br></code></pre></td></tr></table></figure><h3 id="View"><a href="#View" class="headerlink" title="View"></a>View</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-comment"><!-- XAML --></span> <br><span class="hljs-tag"><<span class="hljs-name">Grid</span>></span> <br><span class="hljs-tag"><<span class="hljs-name">ListBox</span> <span class="hljs-attr">ItemsSource</span>=<span class="hljs-string">"{Binding Timezones}"</span>></span><br><span class="hljs-tag"><<span class="hljs-name">ListBox.ItemTemplate</span>></span> <br><span class="hljs-tag"><<span class="hljs-name">DataTemplate</span>></span> <br><span class="hljs-tag"><<span class="hljs-name">StackPanel</span> <span class="hljs-attr">Orientation</span>=<span class="hljs-string">"Horizontal"</span>></span> <br><span class="hljs-tag"><<span class="hljs-name">TextBlock</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"{Binding Name}"</span> /></span><br><span class="hljs-tag"><<span class="hljs-name">TextBlock</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">":"</span> /></span><br><span class="hljs-tag"><<span class="hljs-name">TextBlock</span> <span class="hljs-attr">Text</span>=<span class="hljs-string">"{Binding Time, StringFormat={}{0:HH:mm:ss}}"</span> /></span><br><span class="hljs-tag"></<span class="hljs-name">StackPanel</span>></span> <br><span class="hljs-tag"></<span class="hljs-name">DataTemplate</span>></span> <br><span class="hljs-tag"></<span class="hljs-name">ListBox.ItemTemplate</span>></span><br><span class="hljs-tag"></<span class="hljs-name">ListBox</span>></span> <br><span class="hljs-tag"></<span class="hljs-name">Grid</span>></span><br></code></pre></td></tr></table></figure><p>这个结构确保了数据和UI的分离,使得代码更加模块化和易于维护。</p>]]></content>
<tags>
<tag>code</tag>
</tags>
</entry>
<entry>
<title>C#入门(从编写控制台程序开始)</title>
<link href="/2024/07/24/C%EF%BC%83%E5%85%A5%E9%97%A8%EF%BC%88%E4%BB%8E%E7%BC%96%E5%86%99%E6%8E%A7%E5%88%B6%E5%8F%B0%E7%A8%8B%E5%BA%8F%E5%85%A5%E9%97%A8%EF%BC%89/"/>
<url>/2024/07/24/C%EF%BC%83%E5%85%A5%E9%97%A8%EF%BC%88%E4%BB%8E%E7%BC%96%E5%86%99%E6%8E%A7%E5%88%B6%E5%8F%B0%E7%A8%8B%E5%BA%8F%E5%85%A5%E9%97%A8%EF%BC%89/</url>
<content type="html"><![CDATA[<h2 id="文件结构"><a href="#文件结构" class="headerlink" title="文件结构"></a>文件结构</h2><p>sln:解决方案文件,里面包含整个解决方案的信息,可以双击运行<br>.csproj:项目文件,里面包含着这个项目的信息,可以双击运行</p><h2 id="书写代码需要注意的地方"><a href="#书写代码需要注意的地方" class="headerlink" title="书写代码需要注意的地方"></a>书写代码需要注意的地方</h2><ol><li>代码中出现的所有标点都是英文半角 shift键快速切换中文半角和英文半角<br>shift+”空格”切换全角/半角</li><li>在C#中,每行代码都以 <code>;</code> 分号结束,注意:这个分号也是英文半角的符号</li><li>Console.WriteLine(“要打印的内容”)<br><code>Console.ReadKey();</code><br>//暂停当前程序,等待用户按下任意键继续,按下的任意键将显示在控制台中</li></ol><h2 id="Visual-Studio-常用快捷键"><a href="#Visual-Studio-常用快捷键" class="headerlink" title="Visual Studio 常用快捷键"></a>Visual Studio 常用快捷键</h2><ol><li>Ctrl-M-O 折叠所有方法 </li><li>Ctrl-M-P 展开所有方法并停止大纲显示(不可以再折叠了) </li><li>Ctrl-M-M 折叠或展开当前方法 </li><li>Ctrl-M-L 展开所有方法</li><li>Ctrl-K-C 注释当前选中段落</li><li>Ctrl-K-U 取消注释当前选中段落</li><li>F1 转到帮助文档,当光标放在类名称上时,可以直接打开微软官方文档</li><li>Ctrl-K-D 快速对齐所有代码</li><li>Ctrl-J 快速弹出智能提示</li><li>Alt-Enter 快速代码提示</li><li>F5 运行程序 或点击绿色启动按钮</li><li>Ctrl+S 保存</li><li>Ctrl+Shift+S保存当前所有打开的文件</li></ol><h2 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h2><p>用在代码前面注销代码能让代码不执行<br>用在代码后面解释该行代码的作用</p><h3 id="1、单行注释"><a href="#1、单行注释" class="headerlink" title="1、单行注释"></a>1、单行注释</h3> <figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-comment">//注释内容</span><br></code></pre></td></tr></table></figure><h3 id="2、多行注释"><a href="#2、多行注释" class="headerlink" title="2、多行注释"></a>2、多行注释</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-comment">/* </span><br><span class="hljs-comment">多行</span><br><span class="hljs-comment">注释</span><br><span class="hljs-comment">内容</span><br><span class="hljs-comment">*/</span><br></code></pre></td></tr></table></figure><p>还有另一种写法:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-comment">/*</span><br><span class="hljs-comment"> *这是</span><br><span class="hljs-comment"> *多行注释</span><br><span class="hljs-comment"> *的</span><br><span class="hljs-comment"> *另一种写法</span><br><span class="hljs-comment"> */</span><br></code></pre></td></tr></table></figure><h3 id="3,文档注释(用于解释方法或类的作用)"><a href="#3,文档注释(用于解释方法或类的作用)" class="headerlink" title="3,文档注释(用于解释方法或类的作用)"></a>3,文档注释(用于解释方法或类的作用)</h3><p>一种xml文档格式的注释方法。</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-comment"><span class="hljs-doctag">///</span><span class="hljs-doctag"><summary></span></span><br><span class="hljs-comment"><span class="hljs-doctag">///</span>注释,解释该方法的作用</span><br><span class="hljs-comment"><span class="hljs-doctag">///</span><span class="hljs-doctag"></summary></span></span><br></code></pre></td></tr></table></figure><p>相关笔记:[[文档注释]] </p><h2 id="集合"><a href="#集合" class="headerlink" title="集合"></a>集合</h2><p>List(泛型集合)的常用方法</p><ol><li>List. Add(T item); 添加一个元素</li><li><code>List. AddRange(IEnumerable<T> collection);</code> 添加一组元素</li><li>Insert(int index, T item); 在index位置添加一个元素</li><li>foreach (T element in mList) Console.WriteLine(element); //T的类型与mList声明时一样 遍历List中元素</li><li>List. Remove(T item)删除一个值</li><li>List. RemoveAt(int index);删除下标为index的元素</li><li>List. RemoveRange(int index, int count);从下标index开始,删除count个元素</li><li>List. Sort () 默认是元素第一个字母按升序</li></ol><h2 id="序列化和反序列化"><a href="#序列化和反序列化" class="headerlink" title="序列化和反序列化"></a>序列化和反序列化</h2><p>json解析时可以使用C#官方提供的newtonjson库,一些典型的使用方式可在[[Newtonsoft.Json]]查看。</p><h2 id="命名规则"><a href="#命名规则" class="headerlink" title="命名规则"></a>命名规则</h2><p>![[驼峰命名法]]<br>![[匈牙利记号法]]</p><p>Pascal命名法:要求每个单词的首字母大写,其余字母小写,多用于给方法或类命名。</p><h2 id="转义符"><a href="#转义符" class="headerlink" title="转义符"></a>转义符</h2><p>定义:转义符是一个 <code>\</code> +一个特殊字符,组成一个有特殊意义的字符<br><code>\r\n</code>:表示回车换行<br><code>\"</code>:表示一个英文半角的双引号<br><code>\t</code>:表示一个tab键的空格<br><code>\b</code>:表示一个退格键,放到字符串的开头和结尾不起作用。<br><code>\\</code>:表示一个 <code>\</code></p><p> <code>@</code> 符号</p><ul><li>用在 <code>\</code> 前,取消其转义作用,使其表示一个 <code>\</code><br> <code>@\</code></li><li>将字符串按照编辑原格式输出</li></ul>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>正态分布</title>
<link href="/2024/07/24/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83/"/>
<url>/2024/07/24/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83/</url>
<content type="html"><![CDATA[<p>正态分布,也被称为高斯分布,是一种在自然界和社会科学中广泛出现的概率分布。它由两个参数决定:均值(mu, μ)和标准差(sigma, σ)。这两个参数完全决定了正态分布的形状和位置。</p><p>一般公式:</p><p>$$<br>f(x; \mu, \sigma) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}<br>$$</p><p>μ=0,σ=1 时,正态分布称为标准分布</p><p>$$<br>f(x)={\frac{1}{\sqrt{2\pi}}e}^{(-\frac{x^2}{2})}<br>$$</p><ul><li>均值 ( $\mu$ ) 决定了正态分布曲线的中心位置。</li><li>标准差 ( $\sigma$ ) 影响曲线的宽度和峰值的高度。</li><li>峰值总是位于均值处,其高度与标准差成反比。</li></ul><h2 id="均值(μ)"><a href="#均值(μ)" class="headerlink" title="均值(μ)"></a>均值(μ)</h2><p>均值是正态分布的中心位置,表示数据集的平均值。在正态分布的图形中,均值决定了分布曲线的对称轴的位置。换句话说,正态分布关于均值对称,数据点围绕均值分布。</p><h2 id="标准差(σ)"><a href="#标准差(σ)" class="headerlink" title="标准差(σ)"></a>标准差(σ)</h2><p>标准差衡量数据点相对于均值的离散程度。具体而言,它表示数据点与均值之间的平均距离。标准差越大,数据点分布得越分散,正态分布曲线越平坦;标准差越小,数据点越集中,正态分布曲线越尖锐。</p><h2 id="控制函数的y极值点"><a href="#控制函数的y极值点" class="headerlink" title="控制函数的y极值点"></a>控制函数的y极值点</h2><p>在一般公式中,( $\sigma$ ) 不仅影响曲线的宽度,还影响曲线的最大高度。具体地,正态分布的峰值(y极值点)出现在 ( x = $\mu$ ),也就是均值处。该点的y值(即峰值的高度)由下面的表达式给出: </p><p>$$<br>f(\mu; \mu, \sigma) = \frac{1}{\sigma\sqrt{2\pi}}<br>$$</p><p>这意味着,峰值的高度与标准差 ( \sigma ) 成反比。标准差越小,峰值越高;标准差越大,峰值越低。</p>]]></content>
<tags>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>良好的代码风格</title>
<link href="/2024/07/24/%E8%89%AF%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81%E9%A3%8E%E6%A0%BC/"/>
<url>/2024/07/24/%E8%89%AF%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81%E9%A3%8E%E6%A0%BC/</url>
<content type="html"><![CDATA[<p>良好的代码风格不仅能提高代码的可读性和可维护性,还能促进团队协作,减少出错的可能性。以下是一些关键的代码风格建议,适用于各种编程语言,特别是C#:</p><h3 id="1-一致性"><a href="#1-一致性" class="headerlink" title="1. 一致性"></a>1. <strong>一致性</strong></h3><ul><li><strong>一致的命名约定</strong>:遵循统一的命名规则,如PascalCase用于类和方法,[[驼峰命名法|camelCase]]用于局部变量和参数。</li><li><strong>一致的缩进和空白</strong>:统一使用空格或制表符进行缩进,并保持一致的缩进级别。</li></ul><h3 id="2-命名"><a href="#2-命名" class="headerlink" title="2. 命名"></a>2. <strong>命名</strong></h3><ul><li><strong>有意义的命名</strong>:变量、方法、类和其他标识符的名称应该清晰、描述性强,并反映其用途。</li><li><strong>避免缩写</strong>:除非是广泛使用的缩写,否则应尽量避免使用。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-built_in">int</span> <span class="hljs-title">CalculateAnnualSalary</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> monthlySalary</span>)</span> { ... } <span class="hljs-comment">// 好的命名</span><br><span class="hljs-function"><span class="hljs-built_in">int</span> <span class="hljs-title">CalcAnnSal</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> mSal</span>)</span> { ... } <span class="hljs-comment">// 不好的命名</span><br></code></pre></td></tr></table></figure><h3 id="3-注释"><a href="#3-注释" class="headerlink" title="3. 注释"></a>3. <strong>注释</strong></h3><ul><li><strong>注释目的</strong>:解释为什么某段代码存在或某种方式实现,而不仅仅是代码在做什么。</li><li><strong>避免过度注释</strong>:代码应该尽量做到自解释,仅在必要时添加注释。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-comment">// 计算年薪</span><br><span class="hljs-function"><span class="hljs-built_in">int</span> <span class="hljs-title">CalculateAnnualSalary</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> monthlySalary</span>)</span><br>{<br> <span class="hljs-keyword">return</span> monthlySalary * <span class="hljs-number">12</span>; <span class="hljs-comment">// 乘以12获得年薪</span><br>}<br></code></pre></td></tr></table></figure><h3 id="4-代码结构"><a href="#4-代码结构" class="headerlink" title="4. 代码结构"></a>4. <strong>代码结构</strong></h3><ul><li><strong>方法简洁</strong>:每个方法应该完成一个明确的任务,长度适中,尽量避免过长的方法。</li><li><strong>类职责单一</strong>:每个类应遵循单一职责原则,即一个类只负责一个功能区域。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span><br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> MonthlySalary { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> <span class="hljs-title">CalculateAnnualSalary</span>()</span><br> {<br> <span class="hljs-keyword">return</span> MonthlySalary * <span class="hljs-number">12</span>;<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="5-异常处理"><a href="#5-异常处理" class="headerlink" title="5. 异常处理"></a>5. <strong>异常处理</strong></h3><ul><li><strong>使用适当的异常类型</strong>:捕获和处理具体的异常类型,而不是通用异常。</li><li><strong>避免空的catch块</strong>:在catch块中应记录异常或进行必要的处理,而不是简单地忽略。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">try</span><br>{<br> <span class="hljs-comment">// 可能引发异常的代码</span><br>}<br><span class="hljs-keyword">catch</span> (SpecificException ex)<br>{<br> <span class="hljs-comment">// 处理特定异常</span><br> Console.WriteLine(ex.Message);<br>}<br><span class="hljs-keyword">catch</span> (Exception ex)<br>{<br> <span class="hljs-comment">// 处理所有其他异常</span><br> Console.WriteLine(<span class="hljs-string">"An error occurred: "</span> + ex.Message);<br>}<br></code></pre></td></tr></table></figure><h3 id="6-代码复用"><a href="#6-代码复用" class="headerlink" title="6. 代码复用"></a>6. <strong>代码复用</strong></h3><ul><li><strong>避免重复代码</strong>:提取公共代码段到独立的方法或类中,提高代码的复用性。</li><li><strong>使用继承和接口</strong>:合理使用继承和接口来实现代码复用和多态。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">ISalaryCalculator</span><br>{<br> <span class="hljs-function"><span class="hljs-built_in">int</span> <span class="hljs-title">CalculateAnnualSalary</span>()</span>;<br>}<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span> : <span class="hljs-title">ISalaryCalculator</span><br>{<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> MonthlySalary { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> <span class="hljs-title">CalculateAnnualSalary</span>()</span><br> {<br> <span class="hljs-keyword">return</span> MonthlySalary * <span class="hljs-number">12</span>;<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="7-测试"><a href="#7-测试" class="headerlink" title="7. 测试"></a>7. <strong>测试</strong></h3><ul><li><strong>编写单元测试</strong>:为每个方法编写单元测试,确保代码的正确性。</li><li><strong>测试覆盖率</strong>:确保测试覆盖代码的主要逻辑分支。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs csharp">[<span class="hljs-meta">TestClass</span>]<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeTests</span><br>{<br> [<span class="hljs-meta">TestMethod</span>]<br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">CalculateAnnualSalary_ShouldReturnCorrectValue</span>()</span><br> {<br> <span class="hljs-keyword">var</span> employee = <span class="hljs-keyword">new</span> Employee { MonthlySalary = <span class="hljs-number">1000</span> };<br> <span class="hljs-keyword">var</span> result = employee.CalculateAnnualSalary();<br> Assert.AreEqual(<span class="hljs-number">12000</span>, result);<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="8-使用现代语言特性"><a href="#8-使用现代语言特性" class="headerlink" title="8. 使用现代语言特性"></a>8. <strong>使用现代语言特性</strong></h3><ul><li><strong>使用LINQ</strong>:在处理集合时,优先使用LINQ以提高代码的简洁性和可读性。</li><li><strong>使用Lambda表达式</strong>:在合适的场景中使用Lambda表达式和匿名方法。</li></ul><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">var</span> numbers = <span class="hljs-keyword">new</span> List<<span class="hljs-built_in">int</span>> { <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span> };<br><span class="hljs-keyword">var</span> evenNumbers = numbers.Where(n => n % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>).ToList();<br></code></pre></td></tr></table></figure><h3 id="9-版本控制"><a href="#9-版本控制" class="headerlink" title="9. 版本控制"></a>9. <strong>版本控制</strong></h3><ul><li><strong>频繁提交</strong>:保持小而频繁的提交,以便更容易地追踪更改。</li><li><strong>有意义的提交信息</strong>:提交信息应清晰描述所做的更改。</li></ul><h3 id="10-代码审查"><a href="#10-代码审查" class="headerlink" title="10. 代码审查"></a>10. <strong>代码审查</strong></h3><ul><li><strong>定期代码审查</strong>:通过代码审查发现潜在问题,提升团队整体代码质量。</li><li><strong>建设性反馈</strong>:提供具体的、建设性的反馈,而不是简单的批评。</li></ul>]]></content>
<tags>
<tag>code</tag>
</tags>
</entry>
<entry>
<title>灰盒测试</title>
<link href="/2024/07/24/%E7%81%B0%E7%9B%92%E6%B5%8B%E8%AF%95/"/>
<url>/2024/07/24/%E7%81%B0%E7%9B%92%E6%B5%8B%E8%AF%95/</url>
<content type="html"><![CDATA[<p><a href="https://www.zhihu.com/question/265505191">测试中的黑盒测试,灰盒测试等是什么意思? - 知乎 (zhihu.com)</a></p><p>灰盒测试关注输出对于输入的正确性,同时也关注内部表现,但这种关注不象白盒那样详细、完整,只是通过一些表征性的现象、事件、标志来判断的运行状态,有时候输出是正确的,但内部其实已经错误了。<br>这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。</p><p>灰盒测试,是介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅关注输出、输入的正确性,同时也关注程序内部的情况。灰盒测试不像白盒那样详细、完整,但又比黑盒测试更关注程序的内部逻辑,常常是通过一些表征性的现象、事件、标志来判断内部的运行状态。</p><h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><p>灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识和与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。</p><h2 id="学术含义"><a href="#学术含义" class="headerlink" title="学术含义"></a>学术含义</h2><blockquote><p>灰盒(Gray Box)是一种程序或系统上的工作过程被局部认知的装置。<br>灰盒测试,也称作灰盒分析,是基于对程序内部细节有限认知上的软件调试方法。测试者可能知道系统组件之间是如何互相作用的,但缺乏对内部程序功能和运作的详细了解。对于内部过程,灰盒测试把程序看作一个必须从外面进行分析的黑盒。<br>灰盒测试通常与web服务应用一起使用,因为尽管应用程序复杂多变,并不断发展进步,因特网仍可以提供相对稳定的接口。由于不需要测试者接触源代码,因此灰盒测试不存在侵略性和偏见。开发者和测试者间有明显的区别,人事冲突的风险减到最小。然而,灰盒测试相对白盒测试更加难以发现并解决潜在问题,尤其在一个单一的应用中,白盒测试的内部细节可以完全掌握。 灰盒测试结合了白盒测试和黑盒测试的要素。它考虑了用户端、特定的系统知识和操作环境。它在系统组件的协同性环境中评价应用软件的设计。灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识和与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。灰盒测试涉及输入和输出,但使用关于代码和程序操作等通常在测试人员视野之外的信息设计测试。</p></blockquote><h2 id="目的任务"><a href="#目的任务" class="headerlink" title="目的任务"></a>目的任务</h2><p>软件测试是软件开发过程的重要组成部分,是用来确认一个程序的品质或性能是否符合开发之前所提出的一些要求。软件测试就是在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。软件测试是为了发现错误而执行程序的过程。软件测试在软件生存期中横跨两个阶段,通常在编写出每一个模块之后就对它做必要的测试(称为单元测试)。编码和单元测试属于软件生存期中的同一个阶段。在结束这个阶段后对软件系统还要进行各种综合测试,这是软件生存期的另一个独立阶段,即测试阶段。</p><h3 id="目的"><a href="#目的" class="headerlink" title="目的"></a>目的</h3><ul><li>第一是确认软件的质量,其一方面是确认软件做了你所期望的事情(Do the right thing),另一方面是确认软件以正确的方式来做了这个事件(Do it right)。</li><li>第二是提供信息,比如提供给开发人员或程序经理的反馈信息,为风险评估所准备的信息。</li><li>第三软件测试不仅是在测试软件产品的本身,而且还包括软件开发的过程。如果一个软件产品开发完成之后发现了很多问题,这说明此软件开发过程很可能是有缺陷的。因此软件测试的第三个目的是保证整个软件开发过程是高质量的。</li></ul><h3 id="测试任务"><a href="#测试任务" class="headerlink" title="测试任务"></a>测试任务</h3><ul><li>1、寻找Bug;</li><li>2、避免软件开发过程中的缺陷;</li><li>3、衡量软件的品质;</li><li>4、关注用户的需求。</li></ul><h3 id="目标"><a href="#目标" class="headerlink" title="目标"></a>目标</h3><ul><li>1、确保软件的质量;</li><li>2、提高软件质量功能。</li></ul>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>常用变量缩写与简写</title>
<link href="/2024/07/24/%E5%B8%B8%E7%94%A8%E5%8F%98%E9%87%8F%E7%BC%A9%E5%86%99%E7%AE%80%E5%86%99/"/>
<url>/2024/07/24/%E5%B8%B8%E7%94%A8%E5%8F%98%E9%87%8F%E7%BC%A9%E5%86%99%E7%AE%80%E5%86%99/</url>
<content type="html"><![CDATA[<h2 id="通用"><a href="#通用" class="headerlink" title="通用"></a>通用</h2><table><thead><tr><th></th><th>通用</th><th>缩写</th><th>翻译</th><th></th><th>通用</th><th>缩写</th><th>翻译</th></tr></thead><tbody><tr><td>1</td><td>address</td><td>addr</td><td>地址</td><td>56</td><td>hexadecimal</td><td>hex</td><td>十六进制</td></tr><tr><td>2</td><td>application</td><td>app</td><td>应用程序</td><td>57</td><td>original</td><td>orig</td><td>原件</td></tr><tr><td>3</td><td>asynchronization</td><td>asyn</td><td>异步</td><td>58</td><td>return</td><td>rtn</td><td>返回</td></tr><tr><td>4</td><td>average</td><td>avg</td><td>平均数</td><td>59</td><td>repeat</td><td>rpt</td><td>重复</td></tr><tr><td>5</td><td>bitmap</td><td>bmp</td><td>位图</td><td>60</td><td>signal</td><td>sig</td><td>信号</td></tr><tr><td>6</td><td>buffer</td><td>buf</td><td>缓冲区</td><td>61</td><td>status</td><td>stat</td><td>状态</td></tr><tr><td>7</td><td>character</td><td>char</td><td>字符</td><td>62</td><td>stack</td><td>stk</td><td>栈区</td></tr><tr><td>8</td><td>color</td><td>clr</td><td>颜色</td><td>63</td><td>standard</td><td>std</td><td>标准</td></tr><tr><td>9</td><td>command</td><td>cmd</td><td>命令</td><td>64</td><td>trigger</td><td>trig</td><td>触发</td></tr><tr><td>10</td><td>delete</td><td>del</td><td>删除</td><td>65</td><td>background</td><td>bg</td><td>背景</td></tr><tr><td>11</td><td>destination</td><td>dest/dst</td><td>目的地</td><td>66</td><td>escape</td><td>esc</td><td>退出</td></tr><tr><td>12</td><td>decrease</td><td>dec</td><td>减少</td><td>67</td><td>user</td><td>usr</td><td>用户</td></tr><tr><td>13</td><td>device</td><td>dev</td><td>设备</td><td>68</td><td>list</td><td>lst</td><td>列表</td></tr><tr><td>14</td><td>different</td><td>diff</td><td>不同的</td><td>69</td><td>server</td><td>srv</td><td>服务</td></tr><tr><td>15</td><td>directory</td><td>dir</td><td>目录</td><td>70</td><td>manager</td><td>mgr</td><td>管理者</td></tr><tr><td>16</td><td>document</td><td>doc</td><td>文档</td><td>71</td><td>insert</td><td>ins</td><td>插入</td></tr><tr><td>17</td><td>dynamic</td><td>dyna</td><td>动态的</td><td>72</td><td>point</td><td>pt</td><td>点</td></tr><tr><td>18</td><td>environment</td><td>env</td><td>环境</td><td>73</td><td>function</td><td>func</td><td>函数</td></tr><tr><td>19</td><td>error</td><td>err</td><td>错误</td><td>74</td><td>back</td><td>bk</td><td>返回</td></tr><tr><td>20</td><td>execute</td><td>exec</td><td>执行</td><td>75</td><td>break</td><td>brk</td><td>间断</td></tr><tr><td>21</td><td>group</td><td>grp</td><td>组</td><td>76</td><td>date</td><td>dat</td><td>日期</td></tr><tr><td>22</td><td>image</td><td>img</td><td>图像</td><td>77</td><td>edit</td><td>edt</td><td>编辑</td></tr><tr><td>23</td><td>information</td><td>info</td><td>信息</td><td>78</td><td>flag</td><td>flg</td><td>标志</td></tr><tr><td>24</td><td>initialize</td><td>init</td><td>初始化</td><td>79</td><td>grid</td><td>grd</td><td>网格</td></tr><tr><td>25</td><td>library</td><td>lib</td><td>库</td><td>80</td><td>increment</td><td>inc</td><td>增量</td></tr><tr><td>26</td><td>maximum</td><td>max</td><td>最大值</td><td>81</td><td>length</td><td>len</td><td>长度</td></tr><tr><td>27</td><td>minimum</td><td>min</td><td>最小值</td><td>82</td><td>oracle</td><td>ora</td><td>甲骨文数据库</td></tr><tr><td>28</td><td>message</td><td>msg</td><td>消息</td><td>83</td><td>panorama</td><td>pano</td><td>全景</td></tr><tr><td>29</td><td>number</td><td>num</td><td>数字,数,数量</td><td>84</td><td>print</td><td>prn</td><td>打印</td></tr><tr><td>30</td><td>object</td><td>obj</td><td>对象</td><td>85</td><td>program</td><td>prg</td><td>程序</td></tr><tr><td>31</td><td>parameter</td><td>Param</td><td>参数(形参)</td><td>86</td><td>statistic</td><td>stat</td><td>统计</td></tr><tr><td>32</td><td>package</td><td>pkg</td><td>打包</td><td>87</td><td>administrator</td><td>adm</td><td>管理员</td></tr><tr><td>33</td><td>position</td><td>pos</td><td>位置</td><td>88</td><td>database</td><td>db</td><td>数据库</td></tr><tr><td>34</td><td>previous</td><td>pre</td><td>前一个</td><td>89</td><td>change</td><td>chg</td><td>改变</td></tr><tr><td>35</td><td>process/Procedure</td><td>proc</td><td>进程/过程</td><td>90</td><td>click</td><td>clk</td><td>点击</td></tr><tr><td>36</td><td>pointer</td><td>ptr</td><td>指针</td><td>91</td><td>compare</td><td>cmp</td><td>比较</td></tr><tr><td>37</td><td>password</td><td>pwd</td><td>密码</td><td>92</td><td>coordinates</td><td>coord</td><td>坐标</td></tr><tr><td>38</td><td>public</td><td>pub</td><td>公共的</td><td>93</td><td>copy</td><td>cpy</td><td>复制</td></tr><tr><td>39</td><td>reference</td><td>ref</td><td>引用</td><td>94</td><td>current</td><td>cur</td><td>当前的</td></tr><tr><td>40</td><td>source</td><td>src</td><td>源</td><td>95</td><td>dictionary</td><td>dict</td><td>字典</td></tr><tr><td>41</td><td>string</td><td>str</td><td>字符串</td><td>96</td><td>display</td><td>disp</td><td>显示</td></tr><tr><td>42</td><td>summation</td><td>sum</td><td>和</td><td>97</td><td>driver</td><td>drv</td><td>驱动</td></tr><tr><td>43</td><td>synchronization</td><td>sync</td><td>同步</td><td>98</td><td>extend</td><td>ex/ext</td><td>扩展</td></tr><tr><td>44</td><td>system</td><td>sys</td><td>系统</td><td>99</td><td>frame</td><td>frm</td><td>框架/帧</td></tr><tr><td>45</td><td>table</td><td>tbl</td><td>表格</td><td>100</td><td>index</td><td>idx / ndx</td><td>索引</td></tr><tr><td>46</td><td>temporary</td><td>tmp</td><td>临时</td><td>101</td><td>horizontal</td><td>horz</td><td>水平</td></tr><tr><td>47</td><td>text</td><td>txt</td><td>文本</td><td>102</td><td>instance</td><td>ins</td><td>实例</td></tr><tr><td>48</td><td>variable</td><td>var</td><td>变量</td><td>103</td><td>increase</td><td>inc</td><td>增加</td></tr><tr><td>49</td><td>addition</td><td>add</td><td>加法/添加</td><td>104</td><td>link</td><td>lnk</td><td>链接</td></tr><tr><td>50</td><td>argument</td><td>arg</td><td>实参</td><td>105</td><td>middle</td><td>mid</td><td>中间</td></tr><tr><td>51</td><td>array</td><td>arr</td><td>数组</td><td>106</td><td>multiply</td><td>mul</td><td>乘</td></tr><tr><td>52</td><td>calculate</td><td>calc</td><td>计算</td><td>107</td><td>resource</td><td>res</td><td>资源</td></tr><tr><td>53</td><td>configuration</td><td>config</td><td>配置</td><td>108</td><td>select</td><td>sel</td><td>选择</td></tr><tr><td>54</td><td>column</td><td>col</td><td>列</td><td>109</td><td>test</td><td>tst</td><td>测试</td></tr><tr><td>55</td><td>control</td><td>ctrl</td><td>控制</td><td>110</td><td>vertical</td><td>vert</td><td>垂直</td></tr></tbody></table><h2 id="控件"><a href="#控件" class="headerlink" title="控件"></a>控件</h2><table><thead><tr><th></th><th>控件</th><th>缩写</th><th>翻译</th><th></th><th>控件</th><th>缩写</th><th>翻译</th></tr></thead><tbody><tr><td>1</td><td>calendar</td><td>cdr</td><td>日历</td><td>21</td><td>swipeView</td><td>swpvw</td><td>滑动控件</td></tr><tr><td>2</td><td>messageDialog</td><td>msgdlg</td><td>消息框</td><td>22</td><td>switch</td><td>sw</td><td>开关</td></tr><tr><td>3</td><td>drawer</td><td>drw</td><td>抽屉</td><td>23</td><td>tabBar</td><td>tbbr</td><td>tab栏</td></tr><tr><td>4</td><td>buttonGroup</td><td>btngrp</td><td>按钮分组</td><td>24</td><td>textField</td><td>txtfld</td><td>文本输入框</td></tr><tr><td>5</td><td>checkBox</td><td>chk</td><td>复选框</td><td>25</td><td>toolBar</td><td>tlbr</td><td>工具栏</td></tr><tr><td>6</td><td>container</td><td>cntr</td><td>容器</td><td>26</td><td>toolTip</td><td>tltp</td><td>提示框</td></tr><tr><td>7</td><td>button</td><td>btn</td><td>按钮</td><td>27</td><td>toolButton</td><td>tlbtn</td><td>工具按钮</td></tr><tr><td>8</td><td>comboBox</td><td>cmb</td><td>下拉框</td><td>28</td><td>treeView</td><td>trvw</td><td>树形视图</td></tr><tr><td>9</td><td>lable</td><td>lbl</td><td>标签</td><td>29</td><td>layout</td><td>lyt</td><td>布局</td></tr><tr><td>10</td><td>progressBar</td><td>prg</td><td>进度条</td><td>30</td><td>mainMenu</td><td>mmnu</td><td>菜单栏</td></tr><tr><td>11</td><td>pageIndicator</td><td>pgindic</td><td>Tab分页控件</td><td>31</td><td>groupBox</td><td>gbx</td><td>组合框</td></tr><tr><td>12</td><td>radioButton</td><td>rdo</td><td>单选框</td><td>32</td><td>pictureBox</td><td>pic</td><td>图片框</td></tr><tr><td>13</td><td>rangeSlider</td><td>rngsld</td><td>滑块</td><td>33</td><td>listView</td><td>lvw</td><td>列表视图</td></tr><tr><td>14</td><td>scrollView</td><td>svw</td><td>视图滚动</td><td>34</td><td>window</td><td>win(wnd)</td><td>窗口</td></tr><tr><td>15</td><td>scrollBar</td><td>vsb(垂直)/hsb(水平)</td><td>滚动条</td><td>35</td><td>form</td><td>frm</td><td>表单</td></tr><tr><td>16</td><td>slider</td><td>sld</td><td>滑动器</td><td>36</td><td>textBox</td><td>txt</td><td>文本框</td></tr><tr><td>17</td><td>spinBox</td><td>spn</td><td>旋转框</td><td>37</td><td>linkLabel</td><td>llbl</td><td>超链接标签框</td></tr><tr><td>18</td><td>splitView</td><td>spltvw</td><td>分割视图</td><td>38</td><td>dialog</td><td>dlg</td><td>对话框</td></tr><tr><td>19</td><td>stackView</td><td>stackvw</td><td>堆栈视图</td><td>39</td><td>scrollIndicator</td><td>scrlindic</td><td>滚动指示器</td></tr><tr><td>20</td><td>statusBar</td><td>statbr</td><td>状态条</td><td></td><td></td><td></td><td></td></tr></tbody></table>]]></content>
<tags>
<tag>code</tag>
</tags>
</entry>
<entry>
<title>Windows CMD命令行</title>
<link href="/2024/07/24/Windows%20CMD%E5%91%BD%E4%BB%A4%E8%A1%8C/"/>
<url>/2024/07/24/Windows%20CMD%E5%91%BD%E4%BB%A4%E8%A1%8C/</url>
<content type="html"><![CDATA[<h2 id="打开命令行的方式"><a href="#打开命令行的方式" class="headerlink" title="打开命令行的方式"></a>打开命令行的方式</h2><ol><li>当前目录 shift+右键</li><li>当前目录的路径输入 cmd</li><li>新建一个bat文件,假设当前目录是 <code>D:\workshop\resume</code> 写入如下内容:<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bat"><span class="hljs-function">f:</span><br><span class="hljs-function"><span class="hljs-title">cd</span> <span class="hljs-title">worlshop</span></span><br><span class="hljs-function"><span class="hljs-title">cd</span> <span class="hljs-title">resume</span></span><br><span class="hljs-function"><span class="hljs-title">start</span></span><br></code></pre></td></tr></table></figure>就算当前目录不在 <code>D:\workshop\resume</code> ,也能用这种方式打开</li></ol>]]></content>
<tags>
<tag>Windows</tag>
</tags>
</entry>
<entry>
<title>string[] args</title>
<link href="/2024/07/24/string%20args/"/>
<url>/2024/07/24/string%20args/</url>
<content type="html"><![CDATA[<p><code>string[] args</code> 是控制台程序中读取终端输入参数的方式。它作为 <code>Main</code> 方法的参数,用于接收从命令行传递过来的参数数组。下面详细说明 <code>string[] args</code> 的作用和使用方式。</p><h3 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h3><p>在终端中运行一个控制台程序时,可以传递多个参数给程序。例如,如果运行以下命令:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sh">MyApp.exe arg1 arg2 arg3<br></code></pre></td></tr></table></figure><p>这些参数会传递给 <code>Main</code> 方法中的 <code>args</code> 数组,即:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] args</span>)</span><br></code></pre></td></tr></table></figure><p>在这个例子中,<code>args</code> 数组将包含以下内容:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs csharp">args[<span class="hljs-number">0</span>] = <span class="hljs-string">"arg1"</span><br>args[<span class="hljs-number">1</span>] = <span class="hljs-string">"arg2"</span><br>args[<span class="hljs-number">2</span>] = <span class="hljs-string">"arg3"</span><br></code></pre></td></tr></table></figure><h3 id="使用示例"><a href="#使用示例" class="headerlink" title="使用示例"></a>使用示例</h3><p>以下是一个简单的示例程序,展示如何使用 <code>string[] args</code> 读取和处理命令行参数:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">using</span> System;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] args</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (args.Length == <span class="hljs-number">0</span>)<br> {<br> Console.WriteLine(<span class="hljs-string">"No arguments provided."</span>);<br> <span class="hljs-keyword">return</span>;<br> }<br><br> Console.WriteLine(<span class="hljs-string">"Arguments received:"</span>);<br> <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> arg <span class="hljs-keyword">in</span> args)<br> {<br> Console.WriteLine(arg);<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>如果在终端中运行 <code>MyApp.exe arg1 arg2 arg3</code>,程序会输出:</p><figure class="highlight coq"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs coq"><span class="hljs-keyword">Arguments</span> received:<br>arg1<br>arg2<br>arg3<br></code></pre></td></tr></table></figure><h3 id="实际应用"><a href="#实际应用" class="headerlink" title="实际应用"></a>实际应用</h3><p>为了展示如何解析命令和参数,并执行相应的功能,以下是一个稍微复杂的例子:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">using</span> System;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] args</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (args.Length == <span class="hljs-number">0</span>)<br> {<br> Console.WriteLine(<span class="hljs-string">"Usage: MyApp <command> <parameters>"</span>);<br> <span class="hljs-keyword">return</span>;<br> }<br><br> <span class="hljs-built_in">string</span> command = args[<span class="hljs-number">0</span>];<br> <span class="hljs-built_in">string</span>[] parameters = args.Skip(<span class="hljs-number">1</span>).ToArray();<br><br> <span class="hljs-keyword">switch</span> (command.ToLower())<br> {<br> <span class="hljs-keyword">case</span> <span class="hljs-string">"greet"</span>:<br> Greet(parameters);<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">case</span> <span class="hljs-string">"sum"</span>:<br> Sum(parameters);<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-literal">default</span>:<br> Console.WriteLine(<span class="hljs-string">$"Unknown command: <span class="hljs-subst">{command}</span>"</span>);<br> <span class="hljs-keyword">break</span>;<br> }<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Greet</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] parameters</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (parameters.Length < <span class="hljs-number">1</span>)<br> {<br> Console.WriteLine(<span class="hljs-string">"Usage: MyApp greet <name>"</span>);<br> <span class="hljs-keyword">return</span>;<br> }<br><br> <span class="hljs-built_in">string</span> name = parameters[<span class="hljs-number">0</span>];<br> Console.WriteLine(<span class="hljs-string">$"Hello, <span class="hljs-subst">{name}</span>!"</span>);<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Sum</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] parameters</span>)</span><br> {<br> <span class="hljs-keyword">if</span> (parameters.Length < <span class="hljs-number">2</span>)<br> {<br> Console.WriteLine(<span class="hljs-string">"Usage: MyApp sum <num1> <num2>"</span>);<br> <span class="hljs-keyword">return</span>;<br> }<br><br> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">int</span>.TryParse(parameters[<span class="hljs-number">0</span>], <span class="hljs-keyword">out</span> <span class="hljs-built_in">int</span> num1) && <span class="hljs-built_in">int</span>.TryParse(parameters[<span class="hljs-number">1</span>], <span class="hljs-keyword">out</span> <span class="hljs-built_in">int</span> num2))<br> {<br> Console.WriteLine(<span class="hljs-string">$"Sum: <span class="hljs-subst">{num1 + num2}</span>"</span>);<br> }<br> <span class="hljs-keyword">else</span><br> {<br> Console.WriteLine(<span class="hljs-string">"Both parameters must be integers."</span>);<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="使用第三方库"><a href="#使用第三方库" class="headerlink" title="使用第三方库"></a>使用第三方库</h3><p>为了更复杂的命令行参数解析,可以使用第三方库(如 <code>CommandLineParser</code>)来简化处理过程。以下是使用 <code>CommandLineParser</code> 库的示例:</p><p>.Net安装 <code>CommandLineParser</code> :</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sh">dotnet add package CommandLineParser<br></code></pre></td></tr></table></figure><p>然后,使用该库解析命令行参数:</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">using</span> System;<br><span class="hljs-keyword">using</span> CommandLine;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span><br>{<br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-built_in">string</span>[] args</span>)</span><br> {<br> Parser.Default.ParseArguments<GreetOptions, SumOptions>(args)<br> .MapResult(<br> (GreetOptions opts) => Greet(opts),<br> (SumOptions opts) => Sum(opts),<br> errs => <span class="hljs-number">1</span>);<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-built_in">int</span> <span class="hljs-title">Greet</span>(<span class="hljs-params">GreetOptions opts</span>)</span><br> {<br> Console.WriteLine(<span class="hljs-string">$"Hello, <span class="hljs-subst">{opts.Name}</span>!"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-built_in">int</span> <span class="hljs-title">Sum</span>(<span class="hljs-params">SumOptions opts</span>)</span><br> {<br> Console.WriteLine(<span class="hljs-string">$"Sum: <span class="hljs-subst">{opts.Num1 + opts.Num2}</span>"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">GreetOptions</span><br>{<br> [<span class="hljs-meta">Value(0, MetaName = <span class="hljs-string">"name"</span>, Required = true, HelpText = <span class="hljs-string">"Name to greet."</span>)</span>]<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title">SumOptions</span><br>{<br> [<span class="hljs-meta">Value(0, MetaName = <span class="hljs-string">"num1"</span>, Required = true, HelpText = <span class="hljs-string">"First number."</span>)</span>]<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> Num1 { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br><br> [<span class="hljs-meta">Value(1, MetaName = <span class="hljs-string">"num2"</span>, Required = true, HelpText = <span class="hljs-string">"Second number."</span>)</span>]<br> <span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> Num2 { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>Read The Docs</title>
<link href="/2024/07/24/Read%20the%20Docs/"/>
<url>/2024/07/24/Read%20the%20Docs/</url>
<content type="html"><![CDATA[<p>Read the Docs是一个广受开发者欢迎的文档托管和自动化构建平台,专为软件项目设计,尤其是开源项目。它使得创建、维护和发布易于访问、结构化的文档变得更加简单。以下是Read the Docs的一些核心特点和功能:</p><ol><li><strong>自动化构建</strong>:与GitHub、GitLab、Bitbucket等版本控制系统集成后,每当你的代码库有变动,Read the Docs会自动抓取最新的代码和文档源文件,使用Sphinx或其他文档生成工具(如mkDocs)编译它们,生成HTML格式的文档。这意味着文档总是与代码同步,减少了维护负担。</li><li><strong>多版本支持</strong>:对于需要维护多个版本文档的项目来说,Read the Docs非常有用。它可以基于Git的分支或标签自动为每个版本生成文档,用户可以选择查看特定版本的文档,这对于跟踪项目随时间的演变特别有帮助。</li><li><strong>主题和自定义</strong>:Read the Docs提供了多种预设主题供选择,同时也允许用户自定义CSS,以便与项目的品牌风格保持一致。这有助于创建既专业又具有辨识度的文档界面。</li><li><strong>交互式文档</strong>:支持集成如nbsphinx这样的工具,允许直接在文档中嵌入可执行的Jupyter Notebook,使得文档不仅仅是静态的内容,而是可以交互学习的资源。</li><li><strong>搜索功能</strong>:内置全文搜索功能,使用户能快速找到他们需要的信息,提升了文档的可用性。</li><li><strong>易于导航</strong>:自动生成的目录、索引和交叉引用等功能,帮助用户在文档间高效跳转,理解复杂概念和项目结构。</li><li><strong>API文档集成</strong>:能够自动从代码注释中提取API文档,确保文档与实际代码保持同步,减少手动编写和更新API文档的工作量。</li><li><strong>社区和开源</strong>:作为一个开源项目本身,Read the Docs拥有活跃的社区支持,意味着用户可以获得帮助,同时也能贡献自己的力量使其不断改进。</li><li><strong>访问统计</strong>:提供文档访问统计信息,帮助项目维护者了解哪些部分最受欢迎,从而指导未来的文档优化方向。</li></ol>]]></content>
<tags>
<tag>项目管理</tag>
</tags>
</entry>
<entry>
<title>ORM技术</title>
<link href="/2024/07/24/ORM%E6%A1%86%E6%9E%B6/"/>
<url>/2024/07/24/ORM%E6%A1%86%E6%9E%B6/</url>
<content type="html"><![CDATA[<p>ORM(Object-Relational Mapping,对象关系映射)是一种编程技术,用于将关系型数据库的数据转换为面向对象编程语言中的对象。这种技术允许开发人员在不直接编写SQL语句的情况下操作数据库,而是通过操作这些对象来间接完成数据的增删改查等操作。</p><p>ORM框架的主要优点包括:</p><ol><li><strong>抽象性</strong>:ORM提供了高级别的抽象,使得开发人员能够专注于业务逻辑而不是底层的数据库操作。</li><li><strong>可移植性</strong>:由于ORM层隔离了应用程序和数据库,所以更换不同的数据库系统相对容易,通常只需要更改配置即可。</li><li><strong>减少错误</strong>:通过使用ORM,开发人员可以避免常见的SQL注入攻击,因为ORM会自动处理参数化查询。</li><li><strong>提高生产力</strong>:ORM可以自动生成SQL语句,节省了手动编写SQL的时间,提高了开发效率。</li></ol><p>一些流行的ORM框架包括:</p><ul><li><strong>Hibernate</strong>:Java中最流行的ORM框架之一,提供了强大的功能和良好的性能。</li><li><strong>Entity Framework</strong>:Microsoft提供的.NET框架的一部分,用于.NET应用程序。</li><li><strong>Django ORM</strong>:Python的Django Web框架中内建的ORM,非常易于使用。</li><li><strong>Sequelize</strong>:Node.js中常用的ORM,支持多种数据库。</li><li><strong>Ruby on Rails ActiveRecord</strong>:Rails框架中内建的ORM,遵循“约定优于配置”的原则。</li></ul><p>使用ORM框架时,开发人员需要定义模型类,这些类映射到数据库中的表。每个对象实例代表数据库中的一行记录,而对象的属性则对应于表中的列。通过框架提供的API,可以方便地进行数据的读取、更新、创建和删除操作。</p>]]></content>
<tags>
<tag>SQL</tag>
</tags>
</entry>
<entry>
<title>Newtonsoft.Json库</title>
<link href="/2024/07/24/Newtonsoft.Json/"/>
<url>/2024/07/24/Newtonsoft.Json/</url>
<content type="html"><![CDATA[<p><strong>最常用</strong>:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs C#">Jsonconvert.SerializeObject(Class);<span class="hljs-comment">//</span><br>JsonConvert.DeserializeObject<Class>(json);<span class="hljs-comment">//</span><br></code></pre></td></tr></table></figure><h2 id="1、实体类的Json序列化和反序列化"><a href="#1、实体类的Json序列化和反序列化" class="headerlink" title="1、实体类的Json序列化和反序列化"></a>1、实体类的Json序列化和反序列化</h2><p>常用数据类型</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">public</span> <span class="hljs-built_in">int</span> ID{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>}<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Name{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>;}<br><span class="hljs-keyword">public</span> DateTime Birthday{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>}<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">bool</span> IsVIP{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>}<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">float</span> Account{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>;}<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span>[] Favourites{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>}<br><span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Remark{<span class="hljs-keyword">get</span>;<span class="hljs-keyword">set</span>;}<br></code></pre></td></tr></table></figure><p>创建一个Person实例</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs C#">Person person = <span class="hljs-keyword">new</span> Person<br>{<br>ID=<span class="hljs-number">1</span>,<br>Name=<span class="hljs-string">"张三"</span>,<br>Birthday=DateTime.Parse(<span class="hljs-string">"2000-01-02"</span>),<br>IsVIP=<span class="hljs-literal">true</span>,<br>Account=<span class="hljs-number">12.34f</span>,<br>Favorites=<span class="hljs-keyword">new</span> <span class="hljs-built_in">string</span>[] {<span class="hljs-string">"吃饭"</span>,<span class="hljs-string">"睡觉"</span>}<br>}<br></code></pre></td></tr></table></figure><h3 id="1-1-Json序列化"><a href="#1-1-Json序列化" class="headerlink" title="1.1 Json序列化"></a>1.1 Json序列化</h3><p>返回不缩进的Json字符串</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">Jsonconvert.SerializeObject(person);<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">{<span class="hljs-string">"ID"</span>:<span class="hljs-number">1</span>,<span class="hljs-string">"Name"</span>:<span class="hljs-string">"张三"</span>,<span class="hljs-string">"Birthday"</span>:<span class="hljs-string">"2000-01-02T00:00:00"</span>,<span class="hljs-string">"IsVIP"</span>:<span class="hljs-literal">true</span>,<span class="hljs-string">"Account"</span>:<span class="hljs-number">12.34</span>,<span class="hljs-string">"Favorites"</span>:[<span class="hljs-string">"吃饭"</span>,<span class="hljs-string">"睡觉"</span>],<span class="hljs-string">"Remark"</span>:<span class="hljs-literal">null</span>}<br></code></pre></td></tr></table></figure><p>返回缩进的Json字符串</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JsonConvert.SerializeObject(person, Formatting.Indented);<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs C#">{<br> <span class="hljs-string">"ID"</span>: <span class="hljs-number">1</span>,<br> <span class="hljs-string">"Name"</span>: <span class="hljs-string">"张三"</span>,<br> <span class="hljs-string">"Birthday"</span>: <span class="hljs-string">"2000-01-02T00:00:00"</span>,<br> <span class="hljs-string">"IsVIP"</span>: <span class="hljs-literal">true</span>,<br> <span class="hljs-string">"Account"</span>: <span class="hljs-number">12.34</span>,<br> <span class="hljs-string">"Favorites"</span>: [<br> <span class="hljs-string">"吃饭"</span>,<br> <span class="hljs-string">"睡觉"</span><br> ],<br> <span class="hljs-string">"Remark"</span>: <span class="hljs-literal">null</span><br>}<br></code></pre></td></tr></table></figure><h4 id="在json序列化中动态忽略某些属性或字段"><a href="#在json序列化中动态忽略某些属性或字段" class="headerlink" title="在json序列化中动态忽略某些属性或字段"></a>在json序列化中动态忽略某些属性或字段</h4><p>在字段前加上<code>[JsonIgnore]</code>,字段在序列化时会被忽略<br>也可以使用<code>[ShouldSerialize]</code>使其能够被序列化(对于有seald开放性的属性能生效)</p><p><a href="https://www.cnblogs.com/vsirWaiter/p/17227266.html">C#在Json序列化中动态忽略某些属性或字段 - 威少小二orz - 博客园 (cnblogs.com)</a></p><h3 id="1-2-将不缩进的JSON字符串转成缩进格式"><a href="#1-2-将不缩进的JSON字符串转成缩进格式" class="headerlink" title="1.2 将不缩进的JSON字符串转成缩进格式"></a>1.2 将不缩进的JSON字符串转成缩进格式</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> <span class="hljs-title">JsonIndentation</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> str</span>)</span><br>{<br><span class="hljs-comment">//string str = JsonConvert.SerializeObject(entity);</span><br>JsonSerializer serializer = <span class="hljs-keyword">new</span> JsonSerializer();<br>TextReader tr = <span class="hljs-keyword">new</span> StringReader(str);<br>JsonTextReader jtr = <span class="hljs-keyword">new</span> JsonTextReader(tr);<br><span class="hljs-built_in">object</span> obj = serializer.Deserialize(jtr);<br><span class="hljs-keyword">if</span> (obj != <span class="hljs-literal">null</span>)<br>{<br>StringWriter textWriter = <span class="hljs-keyword">new</span> StringWriter();<br>JsonTextWriter jsonWriter = <span class="hljs-keyword">new</span> JsonTextWriter(textWriter)<br>{<br>Formatting = Formatting.Indented,<br> Indentation = <span class="hljs-number">4</span>,<br> IndentChar = <span class="hljs-string">' '</span><br>};<br>serializer.Serialize(jsonWriter, obj);<br><span class="hljs-keyword">return</span> textWriter.ToString();<br>}<br><span class="hljs-keyword">else</span><br>{<br><span class="hljs-keyword">return</span> str;<br>}<br>}<br></code></pre></td></tr></table></figure><p>或者:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> <span class="hljs-title">JsonIndentation</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> json</span>)</span><br>{<br>JObject obj = JObject.Parse(json);<br><span class="hljs-keyword">return</span> obj.ToString();<br>}<br></code></pre></td></tr></table></figure><h3 id="1-3、其他设置"><a href="#1-3、其他设置" class="headerlink" title="1.3、其他设置"></a>1.3、其他设置</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs C#">JsonSerializerSettings settings = <span class="hljs-keyword">new</span> JsonSerializerSettings();<br><span class="hljs-comment">// 设置日期格式</span><br>settings.DateFormatString = <span class="hljs-string">"yyyy-MM-dd"</span>;<br><span class="hljs-comment">// 忽略空值</span><br>settings.NullValueHandling = NullValueHandling.Ignore;<br><span class="hljs-comment">// 缩进</span><br>settings.Formatting = Formatting.Indented;<br> <br>JsonConvert.SerializeObject(person, settings);<br></code></pre></td></tr></table></figure><p>返回:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs C#">{<br> <span class="hljs-string">"ID"</span>: <span class="hljs-number">1</span>,<br> <span class="hljs-string">"Name"</span>: <span class="hljs-string">"张三"</span>,<br> <span class="hljs-string">"Birthday"</span>: <span class="hljs-string">"2000-01-02"</span>,<br> <span class="hljs-string">"IsVIP"</span>: <span class="hljs-literal">true</span>,<br> <span class="hljs-string">"Account"</span>: <span class="hljs-number">12.34</span>,<br> <span class="hljs-string">"Favorites"</span>: [<br> <span class="hljs-string">"吃饭"</span>,<br> <span class="hljs-string">"睡觉"</span><br> ]<br>}<br></code></pre></td></tr></table></figure><h3 id="1-4、Json反序列化"><a href="#1-4、Json反序列化" class="headerlink" title="1.4、Json反序列化"></a>1.4、Json反序列化</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JsonConvert.DeserializeObject<Person>(json);<br></code></pre></td></tr></table></figure><h2 id="2、Jobject使用"><a href="#2、Jobject使用" class="headerlink" title="2、Jobject使用"></a>2、Jobject使用</h2><h3 id="2-1、创建对象"><a href="#2-1、创建对象" class="headerlink" title="2.1、创建对象"></a>2.1、创建对象</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs C#">JObject obj = <span class="hljs-keyword">new</span> JObject();<br>obj.Add(<span class="hljs-string">"ID"</span>, <span class="hljs-number">11</span>);<br>obj.Add(<span class="hljs-string">"Name"</span>, <span class="hljs-string">"张三1"</span>);<br>obj.Add(<span class="hljs-string">"Birthday"</span>, DateTime.Parse(<span class="hljs-string">"2020-11-02"</span>));<br>obj.Add(<span class="hljs-string">"IsVIP"</span>, <span class="hljs-literal">true</span>);<br>obj.Add(<span class="hljs-string">"Account"</span>, <span class="hljs-number">13.34f</span>);<br><span class="hljs-comment">// 创建数组</span><br>JArray array = <span class="hljs-keyword">new</span> JArray();<br>array.Add(<span class="hljs-keyword">new</span> JValue(<span class="hljs-string">"上班"</span>));<br>array.Add(<span class="hljs-keyword">new</span> JValue(<span class="hljs-string">"下班"</span>));<br>obj.Add(<span class="hljs-string">"Favorites"</span>, array);<br>obj.Add(<span class="hljs-string">"Remark"</span>, <span class="hljs-literal">null</span>);<br></code></pre></td></tr></table></figure><h3 id="2-2、JObject中添加数组"><a href="#2-2、JObject中添加数组" class="headerlink" title="2.2、JObject中添加数组"></a>2.2、JObject中添加数组</h3><p>上例中的代码可以简化为:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JArray array = <span class="hljs-keyword">new</span> JArray(<span class="hljs-string">"上班"</span>, <span class="hljs-string">"下班"</span>);<br></code></pre></td></tr></table></figure><h3 id="2-3、从Json字符串创建JObject"><a href="#2-3、从Json字符串创建JObject" class="headerlink" title="2.3、从Json字符串创建JObject"></a>2.3、从Json字符串创建JObject</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-built_in">string</span> json = <span class="hljs-string">"{\"ID\":11,\"Name\":\"张三1\",\"Birthday\":\"2020-11-02T00:00:00\",\"IsVIP\":true,\"Account\":13.34,\"Favorites\":[\"上班\",\"下班\"],\"Remark\":null}"</span>;<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JObject obj = JObject.Parse(json);<br></code></pre></td></tr></table></figure><h3 id="2-4、从Entity创建JObject"><a href="#2-4、从Entity创建JObject" class="headerlink" title="2.4、从Entity创建JObject"></a>2.4、从Entity创建JObject</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JObject obj = JObject.FromObject(person);<br></code></pre></td></tr></table></figure><p>用匿名对象创建 JObject</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs C#">JObject obj = JObject.FromObject(<span class="hljs-keyword">new</span> { name = <span class="hljs-string">"jack"</span>, age = <span class="hljs-number">28</span> });<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-comment">//显示</span><br>{<br> <span class="hljs-string">"name"</span>: <span class="hljs-string">"jack"</span>,<br> <span class="hljs-string">"age"</span>: <span class="hljs-number">18</span><br>}<br></code></pre></td></tr></table></figure><p>用初始化器</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs C#">JObject obj = <span class="hljs-keyword">new</span> JObject()<br>{<br> { <span class="hljs-string">"name"</span>, <span class="hljs-string">"jack"</span> },<br> { <span class="hljs-string">"age"</span>, <span class="hljs-number">28</span> }<br>};<br></code></pre></td></tr></table></figure><h3 id="2-5、获取值"><a href="#2-5、获取值" class="headerlink" title="2.5、获取值"></a>2.5、获取值</h3><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-built_in">int</span> id;<br><span class="hljs-keyword">if</span> (obj[<span class="hljs-string">"ID"</span>] != <span class="hljs-literal">null</span>)<br>id = obj[<span class="hljs-string">"ID"</span>].Value<<span class="hljs-built_in">int</span>>();<br></code></pre></td></tr></table></figure><h3 id="2-6、获取数组"><a href="#2-6、获取数组" class="headerlink" title="2.6、获取数组"></a>2.6、获取数组</h3><p>Newtonsoft.Json.Linq 不支持直接获取数组,但是可以获取 List,然后再转化为数组。</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-built_in">string</span>[] favorites;<br><span class="hljs-keyword">if</span> (obj[<span class="hljs-string">"Favorites"</span>] != <span class="hljs-literal">null</span>)<br>favorites = obj[<span class="hljs-string">"Favorites"</span>].Value<List<<span class="hljs-built_in">string</span>>>().ToArray();<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Csharp</tag>
</tags>
</entry>
<entry>
<title>Git仓库管理</title>
<link href="/2024/07/24/Git%E4%BB%93%E5%BA%93%E7%AE%A1%E7%90%86/"/>
<url>/2024/07/24/Git%E4%BB%93%E5%BA%93%E7%AE%A1%E7%90%86/</url>
<content type="html"><![CDATA[<h2 id="常见的标记及其含义"><a href="#常见的标记及其含义" class="headerlink" title="常见的标记及其含义"></a>常见的标记及其含义</h2><ul><li><p><strong>M (Modified)</strong>: 这表示文件已被修改,即工作目录中的文件与最近一次提交到仓库的版本相比有差异,但这些改动还没有被添加到暂存区。</p></li><li><p><strong>R (Renamed)</strong>: 表示文件已被重命名。这意味着一个文件的名字被改变,并且这个改名的动作已经被Git追踪到。</p></li><li><p><strong>A (Added)</strong>: 表示文件是新增的,即该文件是首次被加入到Git的跟踪列表中,通常意味着使用了 <code>git add</code>命令但还未提交。</p></li><li><p><strong>C (Copied)</strong>: 类似于A,但表示文件是从另一个文件复制过来并新增到Git跟踪的。</p></li><li><p><strong>D (Deleted)</strong>: 表示文件已被删除,但这个删除操作还未被提交。</p></li><li><p><strong>U (Updated)</strong>: 在某些上下文中,尤其是在解决合并冲突后,可能表示文件已被更新,既可能是内容被自动或手动解决冲突后更新,也可能是由于合并操作导致的状态。</p></li><li><p><strong>T (Typechange)</strong>: 文件类型被改变,比如从普通文件变为符号链接。</p></li><li><p><strong>X</strong> 不是标准的Git状态标记之一,但在某些特定场景或插件使用中,可能会代表特定的自定义状态或标识。</p></li><li><p><strong>绿色标记</strong>:</p><ul><li>对于文件而言,绿色通常表示该文件已被添加到暂存区(staged),意味着通过执行 <code>git add</code>命令,文件的改动已被记录,等待下次提交(commit)。</li><li>如果是新创建的文件显示为绿色,这表示该文件是新增的并且已经添加到了暂存区。</li></ul></li><li><p><strong>黄色标记</strong>:</p><ul><li>对于文件而言,黄色表示文件已被修改但尚未添加到暂存区。这意味着文件在工作目录中有所改动,但还未使用 <code>git add</code>命令将其包含在下一次提交中。</li><li>对于文件夹而言,黄色通常表示该文件夹包含有未被暂存的改动文件,即该文件夹内至少有一个文件被修改但未添加到暂存区。</li></ul></li></ul>]]></content>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>GitBash</title>
<link href="/2024/07/24/GitBash/"/>
<url>/2024/07/24/GitBash/</url>
<content type="html"><![CDATA[<blockquote><p>相比 GitHub Desktop,GitBash 虽然也有 GUI,但实在太简陋了。<br>这里也就是记录一些基础的常用git命令</p></blockquote><p>Git Bash 是一个在 Windows 操作系统上提供<strong>Git 命令行体验的</strong>应用程序。<br>它是一个命令行 shell,用于在系统中使用命令行启用 git。<br>shell 是一种终端应用程序,用于通过书面命令与操作系统交互。<br>Git Bash 是一个在 Windows 操作系统上安装 Bash、一些常见的 bash 实用程序和 Git 的软件包。在 Git Bash 中,用户通过命令与存储库和 git 元素进行交互。</p><h2 id="什么是Git?"><a href="#什么是Git?" class="headerlink" title="什么是Git?"></a>什么是Git?</h2><p>Git是一个版本控制系统,用于在软件开发过程中<strong>跟踪源代码的更改</strong>。它是为协调程序员之间的工作而设计的,但它也可用于跟踪任何文件集中的更改。其目标是通过<strong>版本控制</strong>提高<strong>效率</strong>、<strong>速度</strong>并轻松管理大型项目。每个 git 工作目录都是一个成熟的存储库,具有完整的历史记录和完整的版本跟踪功能,独立于网络访问或中央服务器。 Git 帮助团队应对多人编辑相同文件时容易发生的混乱。</p><h2 id="如何安装?"><a href="#如何安装?" class="headerlink" title="如何安装?"></a>如何安装?</h2><p>官网找到download,打开安装程序后一路点确认就完了</p><h2 id="GitBash命令"><a href="#GitBash命令" class="headerlink" title="GitBash命令"></a>GitBash命令</h2><table><thead><tr><th>git init</th><th>初始化新的git储存库</th></tr></thead><tbody><tr><td>git clone</td><td>用于克隆远程仓库中已有的储存库</td></tr><tr><td>git add</td><td>工作区中存在的文件将移动到暂存区</td></tr><tr><td>git commit</td><td>暂存区中的文件将被提交到本地存储库</td></tr><tr><td>git status</td><td>该命令显示工作树和暂存区状态</td></tr><tr><td>git log</td><td>查看所有提交的日志</td></tr><tr><td>git branch</td><td>创建一个新的分支</td></tr><tr><td>git merge</td><td>将一个分支的更改合并到另一个分支</td></tr><tr><td>git config</td><td>配置用户名和电子邮件ID</td></tr><tr><td>git tag</td><td>显示所有的标签</td></tr></tbody></table><h2 id="如何使用-GitBash"><a href="#如何使用-GitBash" class="headerlink" title="如何使用 GitBash?"></a>如何使用 GitBash?</h2><h3 id="第-1-步-配置-Git"><a href="#第-1-步-配置-Git" class="headerlink" title="第 1 步: 配置 Git"></a>第 1 步: 配置 Git</h3><p>设置全局用户名和电子邮件。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs c">git config --global user.name<span class="hljs-string">"FIRST_NAME LAST_NAME"</span><br><span class="hljs-comment">//命令行里显然无法一次输入两行命令</span><br>git config --global user.email<span class="hljs-string">"[email protected]"</span><br></code></pre></td></tr></table></figure><p><code>cd</code>命令用于切换路径。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">cd folder_name<br></code></pre></td></tr></table></figure><p><code>ls</code>命令用于列出当前目录下所有的文件和文件夹。<br>打开GitBanh并使用 <code>cd</code>命令将当前目录更改为本地项目。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">cd Desktop/newRepo<br></code></pre></td></tr></table></figure><h3 id="第-2-步-在-Git-Bash-中提交存储库"><a href="#第-2-步-在-Git-Bash-中提交存储库" class="headerlink" title="第 2 步: 在 Git Bash 中提交存储库"></a>第 2 步: 在 Git Bash 中提交存储库</h3><p>将本地目录初始化为 Git 存储库。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git init<br></code></pre></td></tr></table></figure><p>通过将文件添加到本地存储库来暂存第一次提交的文件。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git add<br></code></pre></td></tr></table></figure><p>通过”git status”,可以看到提交在本地存储库中暂存的文件。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git commit -m<span class="hljs-string">"First commit"</span><br></code></pre></td></tr></table></figure><p>现在执行”git status”命令后,可以看到没有任何东西可以提交,因为所有文件都已提交。</p><h3 id="第-3-步-初始化本地-Git-存储库"><a href="#第-3-步-初始化本地-Git-存储库" class="headerlink" title="第 3 步: 初始化本地 Git 存储库"></a>第 3 步: 初始化本地 Git 存储库</h3><p>使用 github 在线,或 GitHub Desktop 指定合适的名称并创建新存储库。</p><h3 id="第-4-步-将本地仓库连接到GitHub"><a href="#第-4-步-将本地仓库连接到GitHub" class="headerlink" title="第 4 步: 将本地仓库连接到GitHub"></a>第 4 步: 将本地仓库连接到GitHub</h3><p>转到 GitHub 仓库,在代码中复制URL,然后再命令提示符中添加推送本地存储库的存储库的 URL。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git remote add orgin repository_URL<br></code></pre></td></tr></table></figure><p>将本地存储库中的更改推送到 GitHub。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git push origin master<br></code></pre></td></tr></table></figure><p>此处文件已被推送到存储库的主分支。现在在GitHub仓库中,就可以看到推送的文件了。</p><h3 id="第-5-步-将更改拉取和推送到-GitBash"><a href="#第-5-步-将更改拉取和推送到-GitBash" class="headerlink" title="第 5 步: 将更改拉取和推送到 GitBash"></a>第 5 步: 将更改拉取和推送到 GitBash</h3><p>假设文件正在更改并且新文件已添加到本地存储库。要将更改保存到 git 存储库中:<br>将所有其他更改从远程存储库下载到本地存储库。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git pull<br></code></pre></td></tr></table></figure><p>必须为提交暂存更改。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git add.<br></code></pre></td></tr></table></figure><p>或者</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git add file_name<br></code></pre></td></tr></table></figure><p>现在提交暂存文件。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git commit -m“commit_name”<br></code></pre></td></tr></table></figure><p>提交变更。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git push orgin master<br></code></pre></td></tr></table></figure><h2 id="如何在-GitBash-中创建和管理分支?"><a href="#如何在-GitBash-中创建和管理分支?" class="headerlink" title="如何在 GitBash 中创建和管理分支?"></a>如何在 GitBash 中创建和管理分支?</h2><ul><li>列出存储库中的所有分支。</li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git branch<br></code></pre></td></tr></table></figure><ul><li>创建一个新分支</li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git branch branch_name<br></code></pre></td></tr></table></figure><ul><li>安全删除指定分支</li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git branch -d branch_name<br></code></pre></td></tr></table></figure><ul><li>强制删除指定分支</li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git branch -D branch_name<br></code></pre></td></tr></table></figure><p>使用 <code>git checkout</code> 在分支之间导航。创建一个新分支并打开它。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git checkout -b new_branch_name<br></code></pre></td></tr></table></figure><p>只需切换到分支</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git checkout branch_name<br></code></pre></td></tr></table></figure><p>签出分支后,您可以在当前分支上看到一个 * 现在也可以在此分支上执行相同的<strong>提交添加</strong>和<strong>提交操作。</strong></p><h2 id="在GitBash中合并分支"><a href="#在GitBash中合并分支" class="headerlink" title="在GitBash中合并分支"></a>在GitBash中合并分支</h2><p>首先,到达目标分支</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git checkout brahcn_name<br></code></pre></td></tr></table></figure><p>将分支合并到目标分支</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git commit new_branc<br></code></pre></td></tr></table></figure><h2 id="GitBash-中的克隆存储库"><a href="#GitBash-中的克隆存储库" class="headerlink" title="GitBash 中的克隆存储库"></a>GitBash 中的克隆存储库</h2><p>克隆用于获取现有 git 存储库的副本。当您运行 <code>git clone</code> 命令时,它会将 zip 文件夹保存在您的默认位置</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git clone url<br></code></pre></td></tr></table></figure><p>此命令将目录保存为 git 存储库的默认目录名称 要将目录名称保存为自定义名称,需要为目录的自定义名称传递一个附加参数</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git clone url custom_name<br></code></pre></td></tr></table></figure><h2 id="在-GitBash-中撤消提交"><a href="#在-GitBash-中撤消提交" class="headerlink" title="在 GitBash 中撤消提交"></a>在 GitBash 中撤消提交</h2><p>当您忘记添加一些要提交的文件并想要撤消任何提交时,可以使用 <code>–amend</code> 再次提交</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">git commit --amend<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>Git提交规范</title>
<link href="/2024/07/24/Git%20%E6%8F%90%E4%BA%A4%E8%A7%84%E8%8C%83/"/>
<url>/2024/07/24/Git%20%E6%8F%90%E4%BA%A4%E8%A7%84%E8%8C%83/</url>
<content type="html"><![CDATA[<p>Git 提交规范是一种约定,用于标准化提交信息,使得项目的历史记录更加清晰、易于理解和维护。这有助于团队成员快速了解每次提交的目的和影响范围。以下是一些常见的提交类型及其含义:</p><ol><li><p><strong>feat (feature)</strong>:</p><ul><li><strong>含义</strong>: 表示新增了一个功能。</li><li><strong>用法示例</strong>: <code>feat: 添加用户评论功能</code>。</li><li><strong>说明</strong>: 这种类型的提交通常涉及到了业务逻辑或用户可见的新功能的增加。</li></ul></li><li><p><strong>fix (修复)</strong>:</p><ul><li><strong>含义</strong>: 用于修复一个已知的错误或“bug”。</li><li><strong>用法示例</strong>: <code>fix: 修正支付流程中的金额计算错误</code>。</li><li><strong>说明</strong>: 当你在代码中解决了某个具体问题时使用此标签。</li></ul></li><li><p><strong>chore</strong>:</p><ul><li><strong>含义</strong>: 指的是那些既不是新增功能也不是修复错误的任务,通常涉及到构建过程或辅助工具的更改。</li><li><strong>用法示例</strong>: <code>chore: 更新依赖包到最新版本</code>。</li><li><strong>说明</strong>: 包括更新配置文件、脚本、构建工具或依赖项等。</li></ul></li><li><p><strong>docs</strong>:</p><ul><li><strong>含义</strong>: 文档更新。</li><li><strong>用法示例</strong>: <code>docs: 完善API文档注释</code>。</li></ul></li><li><p><strong>style</strong>:</p><ul><li><strong>含义</strong>: 代码格式调整,不影响程序逻辑。</li><li><strong>用法示例</strong>: <code>style: 统一代码缩进为4个空格</code>。</li></ul></li><li><p><strong>refactor</strong>:</p><ul><li><strong>含义</strong>: 代码重构,改进现有代码结构和设计,不添加新功能也不修复错误。</li><li><strong>用法示例</strong>: <code>refactor: 重写用户模块以提高性能</code>。</li></ul></li><li><p><strong>test</strong>:</p><ul><li><strong>含义</strong>: 添加或修改测试用例。</li><li><strong>用法示例</strong>: <code>test: 为新功能添加单元测试</code>。</li></ul></li></ol><p>这些提交信息前缀后面通常会跟着一个冒号和一个空格,然后是关于此次提交的简短描述。此外,良好的提交信息还会包含更多的细节,比如为什么要做这个改动,以及它如何解决问题或改进了什么。遵循这样的规范,可以使Git历史记录更加清晰,便于回溯和协作。</p>]]></content>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>经济发展和资本增长的规律</title>
<link href="/2024/06/22/%E7%BB%8F%E6%B5%8E%E5%8F%91%E5%B1%95%E5%92%8C%E8%B5%84%E6%9C%AC%E5%A2%9E%E9%95%BF%E7%9A%84%E8%A7%84%E5%BE%8B/"/>
<url>/2024/06/22/%E7%BB%8F%E6%B5%8E%E5%8F%91%E5%B1%95%E5%92%8C%E8%B5%84%E6%9C%AC%E5%A2%9E%E9%95%BF%E7%9A%84%E8%A7%84%E5%BE%8B/</url>
<content type="html"><![CDATA[<p>基于马克思主义和客观规律,对于经济发展和增长规律的简单总结</p><p>政府的中央银行(铸币权和其所有者)可以通过放出贷款或加息,向市场注入资金,以满足经济运行所需的货币,或以此刺激消费,推动经济增长。</p><blockquote><p>在现代银行业出现之前,钱庄是不会给储蓄者利息的,反而还会收取手续费。因为钱庄的投资手段匮乏,即使有了纸币,其金融能力也很有限。在全球化之前,社会团体之间的交流都非常有限,基本上都是以物易物,根本没有汇率的概念,即使到了二战之后,一段时间内,世界各国还是将黄金作为国际交易结算货币使用。</p></blockquote><p>那么,在没有政府投资手段的古典经济时代,市场是如何增长的呢?</p><p>市场就是商品交换的总和,如果没有政府发行的信用货币,那么在工业革命前金本位市场环境下,一切经济的增长来自于商品和劳动力这样的实际生产要素的增长。在古典经济时代,而无论是金银,农作物,矿物还是服务,都依赖于人口,要想增加商品的产出,必须要依赖于人口的增长。劳动力和资源的投入直接转化为生产力的提升,而经济增长受限于这些实际资源的限制。在新航路开辟和地理大发现之后,银行和保险业的诞生与发展,又推动了对于新大陆人口和资源的掠夺,资本迅速积累,为工业革命奠定基础。</p><p>工业革命通过机械化和专业化生产极大地提高了生产效率,促进了前所未有地经济增长。但是,在工业革命带来的经济繁荣增长,生活水平不断提高的表象下,严重依赖于金本位银本位的经济体制。金本位制度下货币供应量地刚性限制了经济地灵活性,导致金融体系脆弱,埋下了金融危机的种子。</p><p>一战总体而言是后起的帝国主义国家与旧的具有海上霸权的帝国主义国家之间的矛盾,并最终以一场大流感和沙俄帝国的崩溃而告终。一战后旧大陆的帝国主义国家为了偿还战争期间的债务,财政收入降低,对殖民地的掌控力因此严重下降,并且使美国和迎来了发展机遇,成为债权国和资本输出国,日本也在此期间发展成为海上强国。英法主导的分赃会仅仅只是重新瓜分了殖民地利益的划分,却没有对根本矛盾做出任何帮助。20年后,英法等国不仅没有从经济衰退中走出来,英国更是绥靖政策放纵德国扩张,最终导致二战爆发。二战过后,战胜国在又一次的分赃大会上,利用战争期间催生的新技术,新秩序,宣布形成了布雷顿森林体系。通过直接将美元和黄金挂钩,各国不再需要通过严格的货币政策控制货币流通,因金银外流导致的通货紧缩也不再容易发生。现代信用货币体系基本宣告诞生。二战后的独立运动浪潮,其实更多的还是帝国主义国家对于在殖民地的利益和责任的主动切割。在殖民地的资本已经足够强大,能够掌控当地的经济命脉,为什么还要承担当地政府分配利益的责任呢?虽然丧失了一部分利益,但是缩减的支出能够让老牌帝国主义国家尽快还上战争期间欠下贷款,这就足够了。</p><blockquote><p>银行会更愿意向信用良好的还款人借贷,信用良好分为两方面</p><blockquote><p>还款能力,还款人收入债务比(利润率)越高,还款人还款能力也就越高。也即他所剥削的剩余价值越高,生产技术越先进。<br>抵押物即还款人拥有的机械,矿场,土地和水域等自然资源,或他所拥有的股份,金融资产等可出售的有价值资产。</p></blockquote></blockquote><p> 冷战结束以来,尤其是在经历过互联网技术的繁荣发展后,生产力的增长速度逐渐放缓。新的技术在普及,也创造了一批新的增长,例如锂电池技术,光伏发电等。但这些新技术的投入使用过程中,也大量采用了新的生产方式,即采用更多大机械的生产,并且自动化程度提高,这虽然创造了一批更高工作报酬的工程师和技术人员岗位,但是企业所有者往往也获得更高的利润。虽然穷人的生活水平在不断提高,但是和富人之间的差距也在不断拉大,分配不均的矛盾也更大。</p><p>新技术的诞生催生了新的工作岗位,新的产业链,供应链,但是这些新技术相比于20世纪,却并没有提高社会大多数的消费。资本除了剥削剩余价值外,还总是积极的从所有劳动者手中抢走所有的资本。</p>]]></content>
<tags>
<tag>政治经济学</tag>
</tags>
</entry>
<entry>
<title>为什么说赛博朋克绝对不会在现实中上演</title>
<link href="/2024/06/22/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E8%B5%9B%E5%8D%9A%E6%9C%8B%E5%85%8B%E7%BB%9D%E5%AF%B9%E4%B8%8D%E4%BC%9A%E5%9C%A8%E7%8E%B0%E5%AE%9E%E4%B8%AD%E4%B8%8A%E6%BC%94/"/>
<url>/2024/06/22/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4%E8%B5%9B%E5%8D%9A%E6%9C%8B%E5%85%8B%E7%BB%9D%E5%AF%B9%E4%B8%8D%E4%BC%9A%E5%9C%A8%E7%8E%B0%E5%AE%9E%E4%B8%AD%E4%B8%8A%E6%BC%94/</url>
<content type="html"><![CDATA[<h2 id="批判赛博朋克"><a href="#批判赛博朋克" class="headerlink" title="批判赛博朋克"></a>批判赛博朋克</h2><ul><li>资本主义在完成了控制论革命,完全将人类劳动力从生产中剥离出去(通过出让微小的一部分利益让底层相对过剩人口不再反抗,并摧毁政府机关)后,资本家们确实可以完全依赖自动化机械过上完全自由的生活了。</li><li>政府并不是人民创造出来解决社会矛盾的,政府本身是社会矛盾无法调和的产物,它并不具备调和社会矛盾的能力,它其实是既得利益者掌握的防止受压迫者反抗体制摧毁体制的工具。</li></ul><blockquote><p><strong>可变资本</strong>指的是资本家用于购买劳动力的那一部分资本。劳动力在使用过程中,不仅能够创造出补偿劳动力价值的价值,而且能创造出剩余价值,使资本增值。这个剩余价值本身是可变化的,从而转化为劳动力的那部分资本在生产过程中改变自己的价值量,马克思称之为可变资本。资产阶级经济学家只承认<strong>固定资本</strong>和<strong>流动资本</strong>的划分,而不承认不变资本和可变资本的划分。</p><blockquote><p><strong>固定资本</strong>是指以厂房、机器、设备和工具等劳动资料的形式存在的生产资本,是流动资本的对称。它的物质形态全部参加生产过程,虽然受到磨损,但仍然长期保持固定的物质形态。它的价值不是一次全部转移,而是在生产过程中随着磨损一部分一部分地转移到新产品中去。<br><strong>不变资本</strong>是指在剩余价值生产过程中资本家用于购买生产资料的那一部分资本(用字母C表示),即以生产资料形态存在的资本,经过生产过程,它的价值随着物质形态的改变,转移到新产品中去,没有发生任何价值量的变化,价值不会增值。<br>固定资本分析物质的转变和损耗,而不变资本只考虑抽象的价值</p></blockquote></blockquote><ul><li>技术的进步会导致可变资本中用于购买劳动力的那部分资本因劳动力需求下降而下降。由于可变资本不断萎缩,底层民众中会产生大量超过资本雇佣能力的相对过剩人口。而相对过剩人口的增长,又会进一步降低劳资博弈中劳方的谈判力量。</li><li>马克思认为最终会爆发大规模的无产阶级大革命。并且在革命后,生产资料公有制会取代滋养这一切罪恶的私有制经济。然而事实是,发达资本国家的资本收买了本国底层民众,第三世界国家的无产阶级革命者最多只是实现了民族独立,却没能实现全世界无产阶级大团结。</li><li>在马克思主义理论中,无产阶级之所以能够接管世界,是因为无产阶级能够通过阶级革命炸毁生产资料私有制,解决资本主义秩序下周期性的经济危机。<ul><li>无产阶级因具有创造先进生产力的革命性才必然取代资产阶级主导社会生产。</li></ul></li><li>而现实中先进的发达国家通过转嫁矛盾,在凯恩斯主义和新自由主义之间灵活切换,不但度过了一次又一次周期性经济危机,缓和了国内社会矛盾,还挑拨了各国共产者之间的关系。</li><li>人工智能自动化技术的发展和资本的跨国自由流动,在当下都是必然的趋势,但赛博朋克也不可能真的在现实中上演。</li><li>之所以人尤其是无产者必须主动异化这一本质,是因为统治阶级有着指挥社会生产强迫无产者服从社会分工的权力,而之所以统治阶级拥有这种权力或者说之所以必然分裂出执掌权力的统治阶级和服从权力的被统治阶级,是因为人类社会需要组织起生产关系以实现物质的持续再生产。</li><li>当自动化技术满足了脱离人的物质再生产时,也就是生产关系被彻底颠覆之时,也就是分裂为统治与被统治阶级的人类社会阶级结构彻底扬弃之时,也就是人尤其是无产者服从于社会分工的异化本质被打破之时,也就是描述阶级社会的历史唯物主义终结之时。</li><li>自动化技术将终结历史唯物主义,生产力和生产力的矛盾将就此统一。</li><li>自动化技术非但不可能创造一个赛博宇宙,反倒恰是将哪些赛博宇宙中那些精英给吊死在路灯上的最后一根绳!</li></ul>]]></content>
</entry>
<entry>
<title>西方经济学的本色就是删除了殖民掠夺历史后,倒果为因的自圆其说</title>
<link href="/2024/06/22/%E8%A5%BF%E6%96%B9%E7%BB%8F%E6%B5%8E%E5%AD%A6%E7%9A%84%E6%9C%AC%E8%89%B2%E5%B0%B1%E6%98%AF%E5%88%A0%E9%99%A4%E4%BA%86%E6%AE%96%E6%B0%91%E6%8E%A0%E5%A4%BA%E5%8E%86%E5%8F%B2%E5%90%8E%EF%BC%8C%E5%80%92%E6%9E%9C%E4%B8%BA%E5%9B%A0%E7%9A%84%E8%87%AA%E5%9C%86%E5%85%B6%E8%AF%B4/"/>
<url>/2024/06/22/%E8%A5%BF%E6%96%B9%E7%BB%8F%E6%B5%8E%E5%AD%A6%E7%9A%84%E6%9C%AC%E8%89%B2%E5%B0%B1%E6%98%AF%E5%88%A0%E9%99%A4%E4%BA%86%E6%AE%96%E6%B0%91%E6%8E%A0%E5%A4%BA%E5%8E%86%E5%8F%B2%E5%90%8E%EF%BC%8C%E5%80%92%E6%9E%9C%E4%B8%BA%E5%9B%A0%E7%9A%84%E8%87%AA%E5%9C%86%E5%85%B6%E8%AF%B4/</url>
<content type="html"><![CDATA[<p>这种观点反映了部分批评者对于西方经济学传统叙事的质疑,认为其在构建理论体系和分析经济发展模式时,往往忽视了历史上殖民掠夺对全球经济格局形成的深远影响。以下几点可以帮助理解这一批评的具体含义:</p><ol><li><strong>历史背景的忽略</strong>:批评者指出,西方经济学在探讨现代经济体系的起源和发展时,往往侧重于市场机制、技术创新、产权制度等因素,而较少系统性地纳入殖民时期资源掠夺、劳动力剥削、市场强占等历史事实。这些活动为欧洲国家积累了巨额财富,加速了工业化进程,构成了其后续经济发展的初始资本积累。</li><li><strong>因果关系的颠倒</strong>:有观点认为,西方经济学理论有时给人一种印象,即发达国家的繁荣主要是由于其内在的经济体制优越和创新能力,而忽略了这些国家早期通过殖民活动获得的不公平优势。这种论述方式被批评为“倒果为因”,因为它没有充分认识到殖民历史在塑造当前世界经济不平等中的作用。</li><li><strong>发展路径的单一叙事</strong>:西方经济学常推广一套适用于所有国家的经济发展模型,如自由市场、自由贸易等原则,却未充分考虑到不同国家历史起点的差异,尤其是殖民历史对后发国家经济结构和社会形态的深刻影响。这种“一刀切”的发展模式忽视了历史遗留问题的复杂性。</li><li><strong>理论与历史的脱节</strong>:批评者呼吁经济学研究应更加注重历史背景,将殖民掠夺等历史事件作为分析现代经济结构和国际分工的重要维度,以提供一个更为全面和真实的世界经济图景。</li></ol><p>总之,这一批评强调了在探讨经济理论和实践时,必须将历史的复杂性,特别是殖民历史的影响,纳入考量,以避免过于简化且可能具有误导性的理论构建。</p>]]></content>
</entry>
<entry>
<title>马克思主义科学方法论</title>
<link href="/2024/06/22/%E9%A9%AC%E5%85%8B%E6%80%9D%E4%B8%BB%E4%B9%89%E7%A7%91%E5%AD%A6%E6%96%B9%E6%B3%95%E8%AE%BA/"/>
<url>/2024/06/22/%E9%A9%AC%E5%85%8B%E6%80%9D%E4%B8%BB%E4%B9%89%E7%A7%91%E5%AD%A6%E6%96%B9%E6%B3%95%E8%AE%BA/</url>
<content type="html"><![CDATA[<p>马克思主义科学方法论根植于马克思主义哲学之中,特别是其唯物辩证法,这是一种根本性的哲学视角和分析工具,用于理解和改变世界。以下是其核心要点:</p><ol><li><p><strong>唯物主义基础</strong>:马克思主义方法论首先建立在唯物主义的基础之上,认为物质现实是第一性的,意识是第二性的,即物质存在决定意识,而非相反。这意味着在分析任何社会或自然现象时,首先要考虑物质条件和经济基础。</p></li><li><p><strong>辩证法</strong>:马克思主义吸收并改造了黑格尔的辩证法,将其从唯心主义转变为唯物主义辩证法。辩证法强调事物内部矛盾是推动事物发展的动力,事物在对立统一中不断发展变化。这要求观察问题时考虑事物的多面性、过程性和相互联系性。</p></li><li><p><strong>历史唯物主义</strong>:这是马克思主义方法论的一个独特贡献,认为社会存在决定社会意识,生产力的发展是社会变迁的根本原因。历史的推动力在于阶级斗争,以及生产关系与生产力之间的矛盾运动。</p></li><li><p><strong>实践原则</strong>:马克思主义强调理论与实践的统一,认为理论来源于实践,并应服务于实践。真理的标准在于实践的成功与否,主张一切从实际出发,实事求是。</p></li><li><p><strong>全面性与历史性</strong>:分析问题时,要求全面考察事物的各种因素及其历史发展过程,避免片面性和静止的观点。</p></li><li><p><strong>科学社会主义</strong>:基于对资本主义社会矛盾的分析,提出社会主义革命和建设的理论,旨在实现无产阶级的解放和全人类的自由全面发展。</p></li></ol><p>综上所述,马克思主义科学方法论是一种综合的分析框架,它指导我们以科学的态度和方法研究社会与自然,强调理论与实践相结合,动态地、矛盾地看待事物的发展,追求社会公正与人的解放。</p><p>马克思主义科学方法与传统分析方法相比,主要在以下几个方面展现出显著差异:</p><ol><li><p><strong>分析视角的转变</strong>:</p><ul><li><strong>传统分析</strong>往往侧重于表面现象的描述或道德、伦理的评判,有时会基于先验的哲学观念或抽象的原则来解释社会现象,比如强调个人品德、道德规范或君权神授等观念。</li><li><strong>马克思主义科学方法</strong>则强调从物质生产条件出发,关注经济基础如何决定上层建筑(包括政治制度、法律、文化等),以及社会生产力与生产关系之间的矛盾运动如何推动社会发展。这种方法更注重社会现象背后的经济和社会结构因素。</li></ul></li><li><p><strong>历史唯物主义的运用</strong>:</p><ul><li>传统分析可能更多依赖于历史事件的线性叙述或英雄人物的影响力来解释历史变迁。</li><li>马克思主义分析则运用历史唯物主义,认为历史的发展有其客观规律,是生产力与生产关系、经济基础与上层建筑之间矛盾运动的结果,从而提供了一种动态的历史观。</li></ul></li><li><p><strong>辩证法的引入</strong>:</p><ul><li>传统分析可能倾向于静态地看待事物,或者采用简单的因果逻辑。</li><li>马克思主义的唯物辩证法则强调事物内部的矛盾及其发展变化,认为一切事物都是在不断运动、变化和发展中的,这促进了对复杂社会现象的深入理解和多维度分析。</li></ul></li><li><p><strong>实践导向</strong>:</p><ul><li>传统分析可能偏向于理论抽象或纯粹的知识积累。</li><li>马克思主义方法则强调理论与实践的统一,认为理论必须来源于实践,并服务于实践,主张通过革命性的实践来改造社会。</li></ul></li></ol><p>以《中国官僚政治研究》为例,王亚南运用马克思主义方法,不是简单地批评官僚的腐败和个人道德问题,而是从社会经济结构出发,分析官僚政治产生的根本原因及其实质,从而超越了对个别现象的道德谴责,达到了对整个社会制度的深刻批判和理解。这种方法论的差异,使马克思主义分析能够触及问题的本质,提出更加根本的解决方案,而不仅仅是表面上的修修补补。</p>]]></content>
<tags>
<tag>政治经济学</tag>
</tags>
</entry>
<entry>
<title>小镇面包店模型,发币机制</title>
<link href="/2024/06/22/%E5%B0%8F%E9%95%87%E9%9D%A2%E5%8C%85%E5%BA%97%E6%A8%A1%E5%9E%8B%EF%BC%8C%E5%8F%91%E5%B8%81%E6%9C%BA%E5%88%B6/"/>
<url>/2024/06/22/%E5%B0%8F%E9%95%87%E9%9D%A2%E5%8C%85%E5%BA%97%E6%A8%A1%E5%9E%8B%EF%BC%8C%E5%8F%91%E5%B8%81%E6%9C%BA%E5%88%B6/</url>
<content type="html"><![CDATA[<h2 id="中央银行货币发行机制"><a href="#中央银行货币发行机制" class="headerlink" title="中央银行货币发行机制"></a>中央银行货币发行机制</h2><p>为应对潜在的通货紧缩,中央银行采取一系列措施增加货币供应:</p><ul><li><strong>购买国债</strong>:向政府购买国债,新发行货币作为支付方式,政府则利用这些货币支付公共支出,使货币进入流通。</li><li><strong>向商业银行提供贷款</strong>:通过再贴现、再贷款等手段,向商业银行注入新货币,银行再以贷款形式将资金传递给企业和个人。</li><li><strong>公开市场操作</strong>:直接购入政府债券或企业债券,向市场投放货币,增加银行体系的准备金,鼓励贷款,进一步提升货币供给。</li></ul><h2 id="市场的成员:个人,企业,商业银行,中央银行,政府。"><a href="#市场的成员:个人,企业,商业银行,中央银行,政府。" class="headerlink" title="市场的成员:个人,企业,商业银行,中央银行,政府。"></a>市场的成员:个人,企业,商业银行,中央银行,政府。</h2><h3 id="微观经济学:"><a href="#微观经济学:" class="headerlink" title="微观经济学:"></a>微观经济学:</h3><p>个人消费者和企业:主要在微观经济学中研究。个人消费者的行为涉及消费选择、预算约束、效用最大化等;企业则关注生产成本、产量决策、利润最大化以及市场竞争策略。<br>商业银行:在微观经济学中,商业银行的行为可被分析为如何根据利率、信用风险等因素决定贷款和存款政策,以及如何追求利润最大化。商业银行在资金的供需匹配中扮演关键角色,这也属于微观层面的分析。</p><h3 id="宏观经济学:"><a href="#宏观经济学:" class="headerlink" title="宏观经济学:"></a>宏观经济学:</h3><p>中央银行:主要在宏观经济学中分析,因为它负责制定和实施货币政策,如调节货币供应量、设定基准利率等,以影响整体经济的货币条件、控制通货膨胀、促进经济稳定与增长。<br>政府:同样在宏观经济学中占有重要位置,政府的财政政策(如税收、支出、预算赤字)对总需求、就业、经济增长有直接影响,同时也是宏观经济调控的关键工具之一。</p><h2 id="通货膨胀"><a href="#通货膨胀" class="headerlink" title="通货膨胀"></a>通货膨胀</h2><h3 id="成因"><a href="#成因" class="headerlink" title="成因"></a>成因</h3><ol><li><strong>货币供应过多</strong>:政府过度发行货币或银行信贷扩张过快,超出经济实际需求。</li><li><strong>需求拉动</strong>:总需求超过总供给,如经济过热,消费和投资旺盛。</li><li><strong>成本推进</strong>:原材料价格上涨、工资成本上升导致生产成本提高,传导至最终商品和服务价格。</li><li><strong>预期因素</strong>:公众对未来物价上涨的预期促使提前消费和投资,进一步推高物价。</li></ol><h3 id="影响"><a href="#影响" class="headerlink" title="影响"></a>影响</h3><ul><li><strong>个人</strong>:购买力下降,储蓄缩水,生活成本增加。</li><li><strong>企业</strong>:短期内利润可能增加,但长期面临成本上升,消费者购买力下降。</li><li><strong>商业银行</strong>:贷款利率上升,贷款需求减少,但存款增加,利差可能扩大。</li><li><strong>央行</strong>:可能采取加息政策,减少货币供应,控制通胀。</li><li><strong>政府</strong>:税收名义值增加,但实际购买力可能下降,公共支出成本上升。</li></ul><h3 id="应对方式"><a href="#应对方式" class="headerlink" title="应对方式"></a>应对方式</h3><ul><li><strong>个人</strong>:投资抗通胀资产,如股票、房产。</li><li><strong>企业</strong>:提高效率,降低成本,调整定价策略。</li><li><strong>商业银行</strong>:调整贷款结构,增加对优质项目的贷款。</li><li><strong>央行</strong>:提高基准利率,出售政府债券吸收流动性。</li><li><strong>政府</strong>:财政紧缩,减少赤字,优化支出结构。</li></ul><h3 id="未能及时处理通货膨胀的后果:"><a href="#未能及时处理通货膨胀的后果:" class="headerlink" title="未能及时处理通货膨胀的后果:"></a>未能及时处理通货膨胀的后果:</h3><h4 id="个人:"><a href="#个人:" class="headerlink" title="个人:"></a>个人:</h4><ul><li><strong>购买力下降</strong>:随着物价上涨,相同金额的货币购买的商品和服务减少,生活成本增加。</li><li><strong>储蓄缩水</strong>:储蓄和固定收入的价值相对降低,个人财富减少。</li><li><strong>投资决策扭曲</strong>:高通胀环境下,人们倾向于投资实物资产以保值,而非基于长期价值判断。</li></ul><h4 id="企业:"><a href="#企业:" class="headerlink" title="企业:"></a>企业:</h4><ul><li><strong>成本上升</strong>:原材料和劳动力成本增加,压缩利润空间。</li><li><strong>定价策略复杂化</strong>:需要频繁调整价格以反映成本变动,可能损害客户关系。</li><li><strong>投资犹豫</strong>:未来不确定性增加,企业可能推迟扩张和长期投资计划。</li></ul><h4 id="商业银行:"><a href="#商业银行:" class="headerlink" title="商业银行:"></a>商业银行:</h4><ul><li><strong>信贷风险增加</strong>:借款人实际偿还能力随收入购买力下降而降低。</li><li><strong>资产质量下降</strong>:抵押品价值可能因通胀而被高估,增加银行风险。</li><li><strong>利率管理挑战</strong>:需平衡借贷成本与收益,避免不良贷款上升。</li></ul><h4 id="央行:"><a href="#央行:" class="headerlink" title="央行:"></a>央行:</h4><ul><li><strong>政策有效性降低</strong>:长期高通胀可能导致货币政策工具如利率调整效果减弱。</li><li><strong>货币信誉受损</strong>:持续通胀可能削弱货币的国际地位和国内信任度。</li><li><strong>经济调控复杂化</strong>:需要综合运用多种政策工具来遏制通胀,操作难度加大。</li></ul><h4 id="政府:"><a href="#政府:" class="headerlink" title="政府:"></a>政府:</h4><ul><li><strong>财政压力</strong>:通胀推高公共开支,同时税收收入的实际购买力下降。</li><li><strong>社会不满</strong>:民众生活水平下降,可能导致社会不稳定和政府信任度降低。</li><li><strong>资源配置扭曲</strong>:价格信号失真,不利于经济资源的有效配置。</li></ul><h2 id="通货紧缩"><a href="#通货紧缩" class="headerlink" title="通货紧缩"></a>通货紧缩</h2><h3 id="成因-1"><a href="#成因-1" class="headerlink" title="成因"></a>成因</h3><ol><li><strong>货币供应不足</strong>:银行信贷收缩,货币流通速度减慢。</li><li><strong>需求不足</strong>:经济衰退,消费者和企业信心下降,减少支出。</li><li><strong>产能过剩</strong>:供过于求,竞争激烈导致价格下跌。</li><li><strong>预期因素</strong>:预期未来价格更低,推迟消费和投资。</li></ol><h3 id="影响-1"><a href="#影响-1" class="headerlink" title="影响"></a>影响</h3><ul><li><strong>个人</strong>:虽短期内购买力提升,但长期可能面临失业风险,收入减少。</li><li><strong>企业</strong>:销售额下滑,利润减少,库存积压,投资意愿低。</li><li><strong>商业银行</strong>:贷款违约风险增加,信贷收缩,盈利困难。</li><li><strong>央行</strong>:可能降息,增加货币供应,刺激信贷和消费。</li><li><strong>政府</strong>:税收减少,财政收入下降,公共支出压力增大。</li></ul><h3 id="应对方式-1"><a href="#应对方式-1" class="headerlink" title="应对方式"></a>应对方式</h3><ul><li><strong>个人</strong>:增加储蓄,谨慎投资,减少负债。</li><li><strong>企业</strong>:创新和差异化竞争,降低成本,清理库存。</li><li><strong>商业银行</strong>:放宽信贷条件,支持小微企业,增加流动性。</li><li><strong>央行</strong>:降低利率,实施量化宽松,增加货币供给。</li><li><strong>政府</strong>:扩大财政支出,减税,增加公共投资,刺激需求。</li></ul><h3 id="未能及时处理通货紧缩的后果:"><a href="#未能及时处理通货紧缩的后果:" class="headerlink" title="未能及时处理通货紧缩的后果:"></a>未能及时处理通货紧缩的后果:</h3><h4 id="个人:-1"><a href="#个人:-1" class="headerlink" title="个人:"></a>个人:</h4><ul><li><strong>消费意愿降低</strong>:预期价格将进一步下降,推迟购买,导致需求疲软。</li><li><strong>就业困难</strong>:企业缩减规模,新职位减少,失业率上升。</li><li><strong>债务负担加重</strong>:实际债务水平上升,偿债压力增大。</li></ul><h4 id="企业:-1"><a href="#企业:-1" class="headerlink" title="企业:"></a>企业:</h4><ul><li><strong>销售下滑</strong>:市场需求减少,库存积压,利润减少。</li><li><strong>投资减少</strong>:对未来预期悲观,减少扩张和研发投资。</li><li><strong>财务困境</strong>:资产价值下降,资产负债表恶化,融资成本上升。</li></ul><h4 id="商业银行:-1"><a href="#商业银行:-1" class="headerlink" title="商业银行:"></a>商业银行:</h4><ul><li><strong>信贷需求萎靡</strong>:企业和个人借款意愿低,银行盈利能力下降。</li><li><strong>资产质量下降</strong>:贷款违约率可能上升,不良资产增加。</li><li><strong>流动性陷阱</strong>:即使利率极低,也无法刺激借贷和投资。</li></ul><h4 id="央行:-1"><a href="#央行:-1" class="headerlink" title="央行:"></a>央行:</h4><ul><li><strong>政策空间受限</strong>:利率接近零下限,传统货币政策工具效力有限。</li><li><strong>金融稳定性风险</strong>:长期通缩可能引发银行系统性风险。</li><li><strong>信任挑战</strong>:市场对央行刺激经济的能力产生怀疑。</li></ul><h4 id="政府:-1"><a href="#政府:-1" class="headerlink" title="政府:"></a>政府:</h4><ul><li><strong>税收减少</strong>:经济活动放缓,政府税收减少,财政状况恶化。</li><li><strong>刺激政策效果有限</strong>:财政刺激措施可能因需求不足而效果打折。</li><li><strong>长期增长潜力受损</strong>:通缩可能导致经济陷入长期停滞,影响发展潜力。</li></ul><h2 id="中央银行印发的货币是如何进入市场的"><a href="#中央银行印发的货币是如何进入市场的" class="headerlink" title="中央银行印发的货币是如何进入市场的"></a>中央银行印发的货币是如何进入市场的</h2><p>现代社会中,当市场上的商品流通量增加时,如果货币量不变,就会发生通货紧缩,此时需要发行货币,可是中央银行印发的货币又是如何进入市场的呢,举一个通俗的例子讲解一下<br>当市场上的商品流通量增加,如果货币量不变,确实可能导致通货紧缩,因为流通中的货币不再能满足增加的商品交换需求,可能会引起货币购买力上升、物价普遍下降。为了应对这种情况,中央银行可能需要增加货币供应量,以维持经济的平稳运行。下面通过一个通俗的例子来解释中央银行如何将新发行的货币送入市场:<br>假设在一个小镇上,这个小镇上只有一个中央面包店和几家杂货店,居民们用金币进行交易。起初,镇上流通的金币刚好足够大家购买所需的面包和其他杂货,经济运行良好。<br><strong>情况变化</strong>:某一年,镇上的面包店引进了新技术,生产效率大大提高,能产出更多的面包,杂货店也增加了商品种类,整体上市场上的商品流通量增加了。但金币的总量没变,这时<strong>人们发现手中的金币不够用了</strong>,因为要买同样多的面包和其他物品,需要更多的金币。如果金币还是那么多,那么每个金币能买到的东西就变多了,这就是通货紧缩的表现。对个人来说,虽短期内购买力提升,但长期可能由于企业销售额下滑,利润减少,个人会面临失业风险,收入减少,由此会引发贷款违约风险增加,信贷收缩,盈利困难,政府的税收减少,财政收入下降,公共支出压力增大。<br><strong>中央银行行动</strong>:在这个小镇的比喻中,假设有一个类似于中央银行的机构,它意识到这个问题后,决定增发金币来匹配增加的商品供应。中央银行不是简单地把金币扔到街上,而是通过一系列机制让新金币逐步进入流通。<br><strong>具体操作</strong>:这个“中央银行”可能会采取以下步骤:</p><ol><li><strong>购买国债</strong>:它从政府那里购买国债,支付方式是新铸造的金币。政府拿到这些金币后,可以用来支付公共服务项目或补贴,这样金币就流入了经济体系。</li><li><strong>向商业银行提供贷款</strong>:通过再贴现、再贷款等操作,中央银行向商业银行提供新金币作为贷款,银行再将这些资金以贷款的形式提供给企业和个人,企业和个人用这些资金进行投资和消费,金币进一步分散到市场中。</li><li><strong>公开市场操作</strong>:在更复杂的经济环境中,中央银行还可以直接在公开市场上购买资产,比如政府债券或企业债券,向市场注入金币,提高银行体系的准备金,鼓励银行放贷,增加货币供给。<br><strong>最终效果</strong>:随着这些新金币通过不同的渠道进入市场,居民们发现手头的钱多了,可以购买更多商品,之前因商品增多而可能出现的通货紧缩压力得到缓解,经济活动得以继续健康开展。这个过程就像是给干涸的河流注入了新的水源,使得经济之船能够顺利航行。</li></ol><h2 id="长期通胀的后果"><a href="#长期通胀的后果" class="headerlink" title="长期通胀的后果"></a>长期通胀的后果</h2><p>在上述例子中,如果通货紧缩的情况得不到改善,因为某些原因迟迟没有更多金币进入市场,接下来会发生什么<br>如果通货紧缩的情况持续存在,且没有更多的金币(或货币)进入市场,接下来可能会发生以下几种情况:</p><ol><li><strong>物价持续下降</strong>:由于货币供应量相对商品和服务的供应量过少,购买相同数量的商品和服务需要的货币减少,导致物价持续下降。短期内,消费者可能会感到购买力增强,但这也会抑制企业利润。</li><li><strong>消费和投资减少</strong>:随着物价不断下跌,消费者可能会选择推迟购买,期望将来以更低价格购买同样的商品,这种现象被称为“需求递延”。同时,企业面对产品价格下降和未来预期悲观,可能会减少投资,避免在收益不确定的环境下扩大生产。</li><li><strong>企业盈利下降</strong>:物价下跌导致销售收入减少,但企业成本(如固定成本)可能并不会同比例下降,这会压缩企业的利润空间,甚至导致亏损。长期下去,一些企业可能因无法承受亏损而破产或关闭。</li><li><strong>失业率上升</strong>:企业减少投资和生产,可能导致裁员或减少招聘,进而推高失业率。失业人口增加,又会进一步抑制消费需求,形成恶性循环。</li><li><strong>债务负担加重</strong>:在通货紧缩环境中,虽然货币变得更值钱,但对于负债者而言,他们需要支付的固定金额债务实际上变得更加昂贵,因为用更值钱的货币偿还同样面额的债务意味着要付出更多实际价值的货物或服务,这会加重个人和企业的债务负担。</li><li><strong>信贷市场收缩</strong>:银行和其他金融机构可能因为担心贷款难以回收,加上储户偏好现金持有(因为现金随时间增值),而变得不愿意放贷,信贷市场紧缩,进一步抑制经济活动。</li><li><strong>经济衰退</strong>:如果这种情况持续,整个经济体可能会陷入衰退,经济增长停滞,甚至出现负增长。<br>总之,如果通货紧缩的问题得不到解决,可能会对经济造成深远的负面影响,因此政府和中央银行通常会采取积极措施,如前面提到的增加货币供应、降低利率等手段,来防止这种情况的发生或减轻其影响。</li></ol><h2 id="同样以这个小镇面包店的模型为例,在这个模型中发生通货膨胀的可能的原因有哪些?"><a href="#同样以这个小镇面包店的模型为例,在这个模型中发生通货膨胀的可能的原因有哪些?" class="headerlink" title="同样以这个小镇面包店的模型为例,在这个模型中发生通货膨胀的可能的原因有哪些?"></a>同样以这个小镇面包店的模型为例,在这个模型中发生通货膨胀的可能的原因有哪些?</h2><p>在这个小镇面包店的模型中,发生通货膨胀的可能原因主要包括以下几点:</p><ol><li><strong>需求拉动型通货膨胀</strong>:假设小镇的经济突然繁荣,居民收入增加,大家对面包和其他商品的需求急剧上升。如果面包店和其他杂货店的生产能力没有相应扩大,无法满足突然增加的需求,就会出现过多的货币追逐过少的商品的情况。这时,商家可能会提高商品价格以应对供不应求的局面,从而引发通货膨胀。</li><li><strong>成本推动型通货膨胀</strong>:如果面包店的原材料成本上升,比如小麦价格因干旱减产而上涨,或是燃料成本增加导致运输费用上升,面包店为了保持利润水平,可能会提高面包的价格。其他店铺也可能因为类似的成本增加而涨价。这样,整个市场的商品价格都将上涨,导致通货膨胀。</li><li><strong>货币超发</strong>:如果小镇的“中央银行”为了刺激经济或应对财政赤字,无节制地增发金币,而实际的商品和服务并没有相应增加,过多的货币追逐有限的商品,将导致物价普遍上涨,这也是通货膨胀的一个常见原因。</li><li><strong>预期因素</strong>:如果居民和企业预期未来价格会上涨,他们可能会提前增加购买和投资,这种行为本身会加剧需求,推动价格更快上涨,形成一个自我实现的预言,即使没有实质性的供需失衡或成本增加。</li><li><strong>信贷扩张</strong>:如果小镇上的银行放宽信贷条件,导致贷款变得容易获取,居民和企业借贷增加,用于消费和投资的资金增多,也会推高总需求,从而可能引起通货膨胀。</li><li><strong>外部冲击</strong>:小镇经济也可能受到外部因素的影响,比如国际市场大宗商品价格上涨,进口成本增加,或者国际资本流动带来货币供应量的变化,这些都可能成为通货膨胀的触发因素。<br>综上所述,通货膨胀在小镇模型中可能由多种因素单独或共同作用引发,涉及需求、成本、货币供应、预期心理以及外部环境等多个方面。</li></ol><h2 id="通缩时超发的货币引发未来的通胀"><a href="#通缩时超发的货币引发未来的通胀" class="headerlink" title="通缩时超发的货币引发未来的通胀"></a>通缩时超发的货币引发未来的通胀</h2><p>在一个有多种商品流通的市场里,例如我们在这个有小麦田和面包店的小镇里再添加伐木场和家具厂,当小镇能够出口面包后,小镇居民的收入提高,大家希望购买更多家具,但是家具厂无法满足需求,因此家具厂提高了家具的价格。这时家具的价格是虚高的,此时超发的货币会比未来家具厂扩大生产后的币值低,实际上是通货膨胀了。<br>您的描述非常形象地说明了一个特定场景下的通货膨胀过程。让我们详细分析这个过程:</p><ol><li><strong>收入增加导致需求增加</strong>:小镇开始出口面包,居民的收入因此提高,他们的购买力增强,对非必需品如家具的需求也随之上升。这种需求的增长超过了现有家具厂的生产能力。</li><li><strong>供不应求导致价格上升</strong>:家具厂面对突然增加的需求,如果短期内无法扩大生产规模(可能受限于原料、劳动力、设备等因素),无法满足市场需求,按照市场经济的原则,家具厂可能会选择提高价格以平衡供需。这时,家具价格的上涨并不是因为制造成本的直接增加,而是因为需求超过了供给能力,所以您说的“虚高”在这里指的是相对于原本供需平衡状态下的价格而言。</li><li><strong>货币超发加剧通货膨胀</strong>:如果在这个过程中,小镇的“中央银行”为了刺激经济或支持其他项目,发行了超出实际经济增长所需的货币量,这会导致市场上流通的货币总量增加。在商品和服务的供应没有同步增长的情况下,过多的货币追逐相对固定数量的商品,将进一步推高价格,加剧通货膨胀。</li><li><strong>未来生产调整与价格回归</strong>:随着时间的推移,如果家具厂成功扩大生产,增加了市场上的家具供应,理论上供需关系会重新达到平衡,过高的价格可能会逐渐回调。但是,在这个过程中,如果已经发生了明显的通货膨胀,即便未来价格有所回落,之前超发的货币已经造成了总体物价水平的上升,居民手中的货币购买力相对下降,这就是通货膨胀带来的实际损失。<br>总结来说,您提到的情形确实是通货膨胀的一个典型例子,其中包含需求拉动、供给约束以及货币超发的因素。关键在于,即使未来生产扩大后价格可能调整,超发的货币已经导致了整体物价水平的提升,影响了经济的稳定性。</li></ol><h2 id="“滚动债务”或“借新还旧”"><a href="#“滚动债务”或“借新还旧”" class="headerlink" title="“滚动债务”或“借新还旧”"></a>“滚动债务”或“借新还旧”</h2><p>实际上在现实中,随着技术地革新生产力提高,居民和企业的收入和消费的增加带来的税收增加,政府和企业通常会通过借新还旧的方式,只要它们能保证未来的收入是提升的,能够覆盖掉债务的利息,不断地通过新借到的钱偿还以前欠的债,然后用中间的差额去消费和投资<br>确实,您描述的现象在现实经济中是常见的做法,即所谓的“滚动债务”或“借新还旧”。这种方法基于对未来收入增长的信心,允许政府和企业维持或扩大现有的债务规模,同时为当前的消费和投资活动提供资金。以下是这一做法的几个关键点:</p><ol><li><strong>经济增长与税收增加</strong>:随着技术进步和生产力的提高,经济整体倾向于增长,这通常会带动居民和企业收入的增加,进而通过税收等形式增加政府的收入。更高的收入为政府偿还债务提供了基础。</li><li><strong>借新还旧策略</strong>:政府和企业利用新发行债券或其他形式的融资所得,来偿还即将到期的债务本金和利息,而不是一次性全部偿还债务。这样做可以避免一次性大额偿债对现金流的冲击,同时保持资金的连续性使用。</li><li><strong>利息覆盖能力</strong>:关键在于确保新借入资金的利息成本可以被预期的收入增长所覆盖。只要未来的收入增长能够持续,且超过债务成本,这种模式就可以持续运行。</li><li><strong>投资与消费促进</strong>:通过这种方式腾出的资金可以被用于新的投资,比如基础设施建设、教育、研发等领域,或者用于刺激消费,促进经济的进一步增长,形成良性循环。<br>然而,这种策略也有风险,包括:</li></ol><ul><li><strong>债务累积风险</strong>:长期依赖借新还旧可能导致债务总额不断累积,一旦经济增长放缓或遭遇经济危机,收入增长不如预期,可能会难以维持债务的可持续性。</li><li><strong>利息负担加重</strong>:随着债务规模的扩大,即使利率保持不变,总的利息支出也会增加,可能占用越来越多的财政或企业资源。</li><li><strong>信用评级影响</strong>:持续的高额债务和频繁的借新还旧可能会影响政府或企业的信用评级,增加未来融资的成本。<br>因此,虽然借新还旧是一种常用的财务管理策略,但也需要谨慎实施,确保不会积累不可持续的债务风险。</li></ul><h2 id="再贴现"><a href="#再贴现" class="headerlink" title="再贴现"></a>再贴现</h2><p>假设小镇上有一家商业银行,它之前向面包店发放了一笔贷款,面包店用这笔钱购买面粉和燃料,生产出面包销售给居民。一段时间后,面包店开始偿还这笔贷款给商业银行,并附带有利息。然而,有时候面包店可能无法立即以现金还款,而是给了商业银行一张自己开出的、有一定期限的借据(称为“票据”)。这张票据就是面包店承诺在未来某一时间支付给银行一定金额的凭证。<br>这时候,商业银行如果需要增加自己的流动资金(比如为了应对存款提取或新的贷款需求),它可以拿着这张票据去找中央银行,请求中央银行提前兑换现金。这个过程就叫做“再贴现”。中央银行审核票据后,会扣除一定的折扣(即贴现率),(贴现)即中央银行支付给商业银行的款项低于票据面额的部分,这部分差额实际上是商业银行为了提前获得资金所支付的融资成本。然后把剩下的钱给商业银行。这样,商业银行得到了即时的流动性,而中央银行通过这种方式间接向市场注入了新的货币。</p><h2 id="再贷款"><a href="#再贷款" class="headerlink" title="再贷款"></a>再贷款</h2><p>再贷款则是另一种形式的支持。如果商业银行直接向中央银行申请贷款,以补充自身的资金短缺或满足法定准备金要求,这就叫再贷款。比如,小镇的商业银行可能因为居民存款大量提取或贷款需求激增,导致资金紧张。这时,它可以直接向中央银行申请贷款,中央银行审核后会提供所需资金,银行支付一定的利息给中央银行。这个过程中,中央银行实际上是直接向商业银行提供了新增的资金,增加了市场上的货币供应量。</p><h2 id="最后贷款人"><a href="#最后贷款人" class="headerlink" title="最后贷款人"></a>最后贷款人</h2><p>“最后贷款人”是指中央银行在银行体系面临流动性危机时,向遇到资金困难的商业银行或其他合格金融机构提供紧急资金援助的角色。这一机制旨在防范系统性金融风险,确保金融稳定。中央银行作为最后贷款人的主要目标是通过提供必要的流动性支持,帮助遇到临时性资金短缺的金融机构维持正常运营,避免银行挤兑、支付系统中断等危机情况的发生。这一角色的确立强化了中央银行在金融体系中的核心地位,同时也体现了政府作为行政力量在市场经济中的宏观调控作用,其援助并非无条件救助,而是为了稳定市场信心,维护整个金融体系的健康运行。</p><h2 id="央行与商业银行的本质区别"><a href="#央行与商业银行的本质区别" class="headerlink" title="央行与商业银行的本质区别"></a>央行与商业银行的本质区别</h2><ol><li><strong>职能定位</strong>:中央银行主要负责制定和执行货币政策,管理国家货币供应量,控制通货膨胀,以及维护金融稳定。而商业银行则侧重于提供金融服务,如吸收存款、发放贷款、提供支付结算服务等,其目标是追求利润最大化。</li><li><strong>资金来源与使用</strong>:中央银行拥有货币发行权,可以通过多种途径(如购买国债、再贴现、公开市场操作)调节货币供应,而无需提供传统意义上的贷款抵押物。商业银行则依赖于存款、股东资本、金融市场融资等方式获得资金,并基于风险评估和贷款政策向企业和个人提供贷款。</li><li><strong>风险承担与资本要求</strong>:商业银行在发放贷款时,需评估贷款风险并保留相应资本缓冲以应对可能的损失,其运营直接受到市场风险的影响。中央银行作为货币发行者,其信用基础是国家主权,通常不存在破产风险,其风险承担和资本要求与商业银行有本质不同。</li><li><strong>目标与责任</strong>:中央银行的目标是宏观经济稳定,包括控制通货膨胀、促进经济增长、维护金融稳定等,而商业银行的目标是股东回报最大化,即通过有效管理风险和资本,提供金融服务并赚取利润。</li></ol>]]></content>
</entry>
<entry>
<title>哈佛光谱分类</title>
<link href="/2024/06/22/%E5%93%88%E4%BD%9B%E5%85%89%E8%B0%B1%E5%88%86%E7%B1%BB/"/>
<url>/2024/06/22/%E5%93%88%E4%BD%9B%E5%85%89%E8%B0%B1%E5%88%86%E7%B1%BB/</url>
<content type="html"><![CDATA[<p>哈佛系统是天文学家 安妮 江浦 坎农(Annie Jump Cannon) 的一维分类方案,他重新排序了德雷伯(Draper)之前的字母系统。恒星根据其光谱特征按字母表的单个字母进行分组,并可选择使用字母细分。</p><table><thead><tr><th>分类</th><th>温度</th><th>色度</th><th>主序质量</th><th>主序半径</th><th>主序光度</th><th>主序星比例</th></tr></thead><tbody><tr><td>O</td><td>>=33000K</td><td>蓝</td><td>>=16</td><td>>=6.6</td><td>>=30000</td><td>0.00003%</td></tr><tr><td>B</td><td>10000-33000K</td><td>深蓝白色</td><td>2.1-16</td><td>1.8-6.6</td><td>25-30000</td><td>0.12%</td></tr><tr><td>A</td><td>7300-10000K</td><td>蓝白色</td><td>1.4-2.1</td><td>1.4-1.8</td><td>5-25</td><td>0.61%</td></tr><tr><td>F</td><td>6000-73000K</td><td>白</td><td>1.04-1.4</td><td>1.15-1.4</td><td>1.5-5</td><td>3.0%</td></tr><tr><td>G</td><td>5300-6000K</td><td>黄白色</td><td>0.8-1.04</td><td>0.96-1.15</td><td>0.6-1.5</td><td>7.6%</td></tr><tr><td>K</td><td>3900-5300K</td><td>淡黄橙色</td><td>0.45-0.8</td><td>0.7-0.96</td><td>0.08-0.6</td><td>12%</td></tr><tr><td>M</td><td>2300-3900K</td><td>浅橙红色</td><td>0.08-0.45</td><td><=0.7</td><td><=0.08</td><td>76%</td></tr></tbody></table>]]></content>
<tags>
<tag>天文</tag>
</tags>
</entry>
<entry>
<title>官僚垄断资本主义、平台资本主义、数字封建主义</title>
<link href="/2024/06/22/%E5%AE%98%E5%83%9A%E5%9E%84%E6%96%AD%E8%B5%84%E6%9C%AC%E4%B8%BB%E4%B9%89%E3%80%81%E5%B9%B3%E5%8F%B0%E8%B5%84%E6%9C%AC%E4%B8%BB%E4%B9%89%E3%80%81%E6%95%B0%E5%AD%97%E5%B0%81%E5%BB%BA%E4%B8%BB%E4%B9%89/"/>
<url>/2024/06/22/%E5%AE%98%E5%83%9A%E5%9E%84%E6%96%AD%E8%B5%84%E6%9C%AC%E4%B8%BB%E4%B9%89%E3%80%81%E5%B9%B3%E5%8F%B0%E8%B5%84%E6%9C%AC%E4%B8%BB%E4%B9%89%E3%80%81%E6%95%B0%E5%AD%97%E5%B0%81%E5%BB%BA%E4%B8%BB%E4%B9%89/</url>
<content type="html"><![CDATA[<h2 id="官僚垄断资本主义"><a href="#官僚垄断资本主义" class="headerlink" title="官僚垄断资本主义"></a>官僚垄断资本主义</h2><p>官僚垄断资本主义是一种资本主义形式,其中资本主义生产方式与政治权力紧密融合,形成了垄断性的国家垄断资本主义。在这种体系中,政府官僚机构与大资本家集团关系密切,政府通过直接控制或强烈影响关键经济领域,如基础设施、自然资源和重要产业,来维护特定资本利益。官僚垄断资本主义的特征包括:</p><ul><li><strong>政治权力与经济力量的联姻</strong>:政府官员和大型企业之间存在紧密的联系,政府可能直接经营企业或通过法规为特定企业提供保护和优势。</li><li><strong>市场准入限制</strong>:通过政策和法规限制竞争,保护特定企业和行业免受外来竞争,维持垄断地位。</li><li><strong>资源分配不公</strong>:资源和机会倾向于集中在少数政治和经济精英手中,加剧社会不平等。</li><li><strong>决策非市场化</strong>:经济决策往往受到政治考量的影响,而非完全由市场需求驱动。</li></ul><h2 id="平台资本主义"><a href="#平台资本主义" class="headerlink" title="平台资本主义"></a>平台资本主义</h2><p>平台资本主义是数字经济时代的一种新现象,指的是基于互联网平台的商业模式,这些平台通过聚合用户、数据、服务和产品,形成强大的市场中介。平台资本主义的核心特征包括:</p><ul><li><strong>数据驱动</strong>:平台通过收集、分析用户数据,实现精准营销、定制服务,从而创造价值。</li><li><strong>双边市场</strong>:连接供应商和消费者,通过规模经济和网络效应迅速扩张,形成市场垄断或寡头。</li><li><strong>灵活用工</strong>:促进了零工经济和数字劳工的兴起,劳动者与平台的关系趋向松散,权益保护成为挑战。</li><li><strong>监管挑战</strong>:由于其新颖性和跨界性,平台资本主义经常超出传统监管框架,引发关于数据隐私、竞争政策和劳动权益的讨论。</li></ul><h2 id="数字封建主义"><a href="#数字封建主义" class="headerlink" title="数字封建主义"></a>数字封建主义</h2><p>数字封建主义是一个较新的概念,用来形容一种可能的未来社会结构,其中数字平台和科技巨头通过控制数据、算法和关键技术,建立起类似封建时代的等级制度。在这个模型中:</p><ul><li><strong>技术领主与数字农奴</strong>:少数掌握核心数字资源的企业如同领主,而广大用户和依赖平台的工作者则像依附于土地的农奴,他们的生计和活动受限于平台规则。</li><li><strong>信息不对称</strong>:平台拥有对数据的绝对控制权,普通用户对个人信息的使用和价值创造过程缺乏透明度和控制。</li><li><strong>经济依赖性</strong>:用户和小型企业对大平台的服务高度依赖,很难脱离平台生态系统独立生存。</li><li><strong>社会分化加剧</strong>:随着数字鸿沟的加深,技术资源的不平等分配可能导致社会阶层更加固化,形成新的不平等结构。</li></ul>]]></content>
<tags>
<tag>政治经济学</tag>
</tags>
</entry>
<entry>
<title>外汇储备</title>
<link href="/2024/06/22/%E5%A4%96%E6%B1%87%E5%82%A8%E5%A4%87/"/>
<url>/2024/06/22/%E5%A4%96%E6%B1%87%E5%82%A8%E5%A4%87/</url>
<content type="html"><![CDATA[<h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><p>外汇储备是由企业结汇获得的。外汇是由企业出口(或者外资投资)获得的,而企业出口获得的外汇无法直接在国内使用,需要进行兑换,而央行(通过商业银行)获得外汇之后,资产负债表上资产(外汇储备)增加,则需要相应的负债(货币发行)。<br>我持有的美元债务,实际上已经有等额人民币存在于中国市场上。企业去兑换美元(结汇)的时候从银行拿到的人民币,就是对应这笔外汇印出来的钱。这笔人民币叫外汇占款。</p><h2 id="外汇储备的三个用途"><a href="#外汇储备的三个用途" class="headerlink" title="外汇储备的三个用途"></a>外汇储备的三个用途</h2><h3 id="用于国内企业国际结算"><a href="#用于国内企业国际结算" class="headerlink" title="用于国内企业国际结算"></a>用于国内企业国际结算</h3><p>我国企业在进口时,需要美元,就需要用等值的人民币兑换外汇,支付给外国企业。或者外国企业(或者老外在中国工作)在中国赚了钱,需要带回去,就得把手里的人民币换成外汇带走,这个时候就要用到外汇储备,把市场上对应的人民币收回。(央行的资产负债表上资产负债同时减少,相当于回收货币)</p><h3 id="政府间国际援助、结算"><a href="#政府间国际援助、结算" class="headerlink" title="政府间国际援助、结算"></a>政府间国际援助、结算</h3><p>援助、交联合国会费之类。或者国际军火贸易。</p><h3 id="稳定汇率"><a href="#稳定汇率" class="headerlink" title="稳定汇率"></a>稳定汇率</h3><p>在适当的时候在市场上抛售外汇买入人民币使人民币升值</p>]]></content>
<tags>
<tag>政治经济学</tag>
</tags>
</entry>
<entry>
<title>布莱克舒尔斯期权定价模型</title>
<link href="/2024/06/22/%E5%B8%83%E8%8E%B1%E5%85%8B%E8%88%92%E5%B0%94%E6%96%AF%E6%9C%9F%E6%9D%83%E5%AE%9A%E4%BB%B7%E6%A8%A1%E5%9E%8B/"/>
<url>/2024/06/22/%E5%B8%83%E8%8E%B1%E5%85%8B%E8%88%92%E5%B0%94%E6%96%AF%E6%9C%9F%E6%9D%83%E5%AE%9A%E4%BB%B7%E6%A8%A1%E5%9E%8B/</url>
<content type="html"><![CDATA[<p>布莱克-舒尔斯(Black-Scholes)期权定价模型是一种用于计算欧式期权价格的数学模型,被认为是金融工程领域的重要成就之一。它由费希尔·布莱克(Fischer Black)和默顿·舒尔斯(Myron Scholes)在1973年提出,并于1997年诺贝尔经济学奖颁给这两位经济学家,以表彰他们的贡献。</p><h2 id="模型基本假设:"><a href="#模型基本假设:" class="headerlink" title="模型基本假设:"></a>模型基本假设:</h2><ol><li><p><strong>市场假设</strong>:</p><ul><li>市场是有效的,不存在套利机会。</li><li>资产价格遵循几何布朗运动(Geometric Brownian Motion),即其价格的变化服从随机游走模型。</li></ul></li><li><p><strong>基本参数</strong>:</p><ul><li><strong>标的资产价格</strong> $S_t$:标的资产在时间 $t$ 的价格。</li><li><strong>行权价格</strong> $K$:期权的行权价格,即标的资产的约定购买或卖出价格。</li><li><strong>到期时间</strong> $T$:期权的到期时间。</li><li><strong>无风险利率</strong> $r$:期间内可获得的无风险利率。</li><li><strong>标的资产波动率</strong> $\sigma$:标的资产的年化波动率。</li></ul></li></ol><h2 id="模型公式:"><a href="#模型公式:" class="headerlink" title="模型公式:"></a>模型公式:</h2><p>布莱克-舒尔斯模型基于偏微分方程,它的基本公式为:</p><p>$$<br>C(S_t, t) = S_t \cdot N(d_1) - K \cdot e^{-r(T-t)} \cdot N(d_2)<br>$$</p><p>$$<br>P(S_t, t) = K \cdot e^{-r(T-t)} \cdot N(-d_2) - S_t \cdot N(-d_1)<br>$$</p><p>其中:</p><ul><li>$C(S_t, t)$ 和 $P(S_t, t)$ 分别表示欧式看涨期权和看跌期权的价格。</li><li>$N$ 是标准正态分布的累积分布函数。</li><li>$d_1$ 和 $d_2$ 是根据以下公式计算的:</li></ul><p>$$<br>d_1 = \frac{\ln(S_t / K) + (r + \frac{\sigma^2}{2})(T - t)}{\sigma \sqrt{T - t}}<br>$$</p><p>$$<br>d_2 = d_1 - \sigma \sqrt{T - t}<br>$$</p><h2 id="解释和应用:"><a href="#解释和应用:" class="headerlink" title="解释和应用:"></a>解释和应用:</h2><ul><li><strong>定价原理</strong>:布莱克-舒尔斯模型通过考虑标的资产价格的随机波动性、期权行权价格、时间价值和无风险利率,计算出一个合理的期权价格。</li><li><strong>波动率的影响</strong>:模型中的一个关键参数是标的资产的波动率 $\sigma$,它反映了市场对资产未来波动性的预期。波动率越高,期权的价格通常也会越高。</li><li><strong>应用范围</strong>:布莱克-舒尔斯模型主要适用于欧式期权(即只能在到期日行使的期权),并且假设市场是无套利的和免除交易成本的情况下。</li></ul><p>布莱克-舒尔斯模型为金融市场提供了一种理论框架,使得投资者和金融机构能够更准确地定价和交易期权,同时也促进了对金融衍生品定价理论的深入研究和发展。</p>]]></content>
<tags>
<tag>商业</tag>
</tags>
</entry>
<entry>
<title>什么是朋克?</title>
<link href="/2024/03/16/%E4%BB%80%E4%B9%88%E6%98%AF%E6%9C%8B%E5%85%8B%EF%BC%9F/"/>
<url>/2024/03/16/%E4%BB%80%E4%B9%88%E6%98%AF%E6%9C%8B%E5%85%8B%EF%BC%9F/</url>
<content type="html"><![CDATA[<p>朋克的意义就是否定和摧毁固有的与保守的——<strong>然后重建</strong>。</p><p>科幻中的朋克就是借用流行文化里的朋克的概念,把现在的世界形态打碎,在某个时间点里建立一个新形态的世界。例如赛博朋克建立了一个高科技低生活的未来世界,赛博空间和仿生人技术高度发达,并且大部分时候故事背景在太空时代。原子朋克设想了一个原子能高度发达的社会,世界处于冷战背景下,美好的生活随时会化为泡影。蒸汽朋克则是把高科技造物换了个蒸汽机风格的外壳,然后塞到维多利亚时期风格的背景里。朋克是故事的核心,而赛博控制论或蒸汽机则是故事的背景,通过这些有趣的置换,故事的丰富程度得到极大的提高,表达内核的方式也更加丰富。</p><h2 id="赛博朋克"><a href="#赛博朋克" class="headerlink" title="赛博朋克"></a>赛博朋克</h2><blockquote><p>下面这段使用ai模仿生成</p></blockquote><p>赛博朋克是一种深受科幻和网络技术影响的设计风格,它起源于20世纪70年代至80年代的科幻小说和电影,特点是高科技与低生活水平的结合。赛博朋克的典型特征包括高度发达的计算机和网络技术、人工智能、生物工程、霓虹灯和摩天大楼等元素。这种风格通常描绘出一个充满未来感和科技感的世界,但同时也强调了社会的不公和人类道德的沦丧。赛博朋克作品通常探讨人类与机器、真实与虚拟、自由与控制等主题,同时也传达出对现代科技的担忧和对人类未来的思考。在赛博朋克作品中,常常出现一些具有超强能力的黑客、雇佣兵和反抗者等角色。</p><h2 id="原子朋克"><a href="#原子朋克" class="headerlink" title="原子朋克"></a>原子朋克</h2><p>原子朋克是一种比较完整的设计风格,但最开始是始于游戏作品中,原子能进入民用市场,电子管计算机大规模发展并且晶体管还未出现,各种原子朋克风格的物品,颜色鲜艳,线条圆润简洁,充满未来感,构成了不同寻常的世界观。在这类作品中更多的将原子朋克当成一种外观设计语言,并且游戏多发生在后启示录背景下,且多是冷战以大规模核武器互相毁灭后的世界为背景,在不特别说明的情况下,这种故事的背景大多是在美苏冷战时期。这样做方便叙事,且避开了庞大繁杂的社会,主角只需要在辐射废土上演绎他的故事。这种故事也往往传达出强烈的反乌托邦主义思想——即使是在这种有着无限能源的社会中,两大霸主之间的竞争也最后导致了美好的生活和未来一切的消失。</p><p>在2023年2月发售的游戏《原子之心》中,特工P3也是在一片机器人叛乱后的“废土”世界中,逐步揭开理想世界背后的真相。本作中即出现了众多具有鲜明的原子朋克风格设计的机器人,使人想起辐射系列中的“噶爪”等机器人和动力机甲,但该作品不同于《辐射》在于,其非开放世界的线性叙事结构和解谜元素,展现出了更多创作者的设计意图之外,也让美术资源得到了最大化的利用,让玩家充分领略了一个充满了机器人和自动化机械的乌托邦世界,以及失去这一切之后的惨烈现实。</p><h2 id="蒸汽朋克"><a href="#蒸汽朋克" class="headerlink" title="蒸汽朋克"></a>蒸汽朋克</h2><blockquote><p>下面这段使用ai模仿生成</p></blockquote><p>蒸汽朋克是一种以蒸汽动力和工业革命为背景的设计风格,它起源于20世纪80年代至90年代的科幻小说和电影。蒸汽朋克的典型特征包括巨大的齿轮、蒸汽机、煤炭和钢铁等元素,以及维多利亚时代的建筑和服装风格。这种风格通常描绘出一个充满历史感和机械感的时代,但同时也强调了科技和工业的发展对环境和人类的影响。蒸汽朋克作品通常探讨工业革命和科技进步带来的社会变革和道德问题,同时也传达出对现代科技的担忧和对人类未来的思考。在蒸汽朋克作品中,常常出现一些具有独特技能和智慧的发明家、探险家和革命者等角色。</p>]]></content>
</entry>
<entry>
<title>Design on Code(基于代码的设计)</title>
<link href="/2024/03/15/Design%20on%20Code(%E5%9F%BA%E4%BA%8E%E4%BB%A3%E7%A0%81%E7%9A%84%E8%AE%BE%E8%AE%A1)/"/>
<url>/2024/03/15/Design%20on%20Code(%E5%9F%BA%E4%BA%8E%E4%BB%A3%E7%A0%81%E7%9A%84%E8%AE%BE%E8%AE%A1)/</url>
<content type="html"><![CDATA[<p>“Design on Code” 理念,也称为“基于代码的设计”或“编码设计”,是一种软件开发方法,它强调在编写代码的过程中进行设计和规划。这种方法与传统的“先设计后编码”的方法有所不同,它认为设计应该是逐步演进的,而不是在编码之前完全确定的。</p><p>“Design on Code”理念的一些主要特点:</p><ol><li><strong>迭代和演进</strong>:鼓励开发人员通过迭代和演进的方式来构建软件。这意味着设计会在编码过程中逐渐变得清晰,而不是一开始就完全确定。</li><li><strong>灵活性</strong>:由于设计是逐步形成的,提供了更大的灵活性,允许开发人员根据实际需求进行调整和修改。</li><li><strong>代码质量</strong>:通过直接在代码中实现设计,开发人员可以更容易地确保代码的质量和可维护性。鼓励编写简洁、清晰和可测试的代码。</li><li><strong>减少文档</strong>:与传统的设计方法相比,可能不需要编写大量的设计文档。相反,代码本身成为了设计的主要表达形式。</li><li><strong>强调实现</strong>:实现(即编码)是设计过程的重要组成部分。通过编写代码,开发人员可以更好地理解问题的本质,并据此调整设计。</li></ol><p>“Design on Code”理念并不是要完全摒弃传统的设计方法。在某些情况下,先进行详细的设计可能是必要的。然而,这种方法提供了一种不同的视角,强调在编码过程中进行设计和规划的重要性。</p><p>此外,这种方法可能更适合于某些类型的项目,如快速原型开发、敏捷开发或需要高度灵活性和适应性的项目。然而,在其他情况下,传统的先设计后编码方法可能更为合适。因此,在选择使用哪种方法时,需要根据项目的具体需求和团队的实际情况进行权衡。</p>]]></content>
</entry>
<entry>
<title>Unity 绑定(订阅)事件方式</title>
<link href="/2024/03/15/Unity%20%E7%BB%91%E5%AE%9A(%E8%AE%A2%E9%98%85)%E4%BA%8B%E4%BB%B6%E6%96%B9%E5%BC%8F/"/>
<url>/2024/03/15/Unity%20%E7%BB%91%E5%AE%9A(%E8%AE%A2%E9%98%85)%E4%BA%8B%E4%BB%B6%E6%96%B9%E5%BC%8F/</url>
<content type="html"><![CDATA[<p>绑定事件的本质是delegate委托,C#本身封装了一个Event类(配合EventArgs使用更方便),Unity又封装了UnityEvent和UnityAction(然后就可以在unity的inspector里通过拖动脚本或物体来绑定事件)。<br>所以addlistener方法除了可以传入void参数的方法,使用 <code>addlistener(nameof(methodname));</code> 也可以传入委托,或使用表达式主体,即把委托声明放在了表达式里而不是由编译器来构造委托。<br>事先强调一下这一点,之后就不用再回答一个低级问题了:“如何在addlistener()时为订阅的事件(方法)传入事件参数?”</p><h2 id="UGUI几种绑定事件的方法"><a href="#UGUI几种绑定事件的方法" class="headerlink" title="UGUI几种绑定事件的方法"></a>UGUI几种绑定事件的方法</h2><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">using</span> System.Collections;<br><span class="hljs-keyword">using</span> System.Collections.Generic;<br><span class="hljs-keyword">using</span> UnityEngine;<br><span class="hljs-keyword">using</span> UnityEngine.EventSystems;<br><span class="hljs-keyword">using</span> UnityEngine.UI;<br> <br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">NewBehaviourScript</span> : <span class="hljs-title">MonoBehaviour</span> {<br> <br> Button btn;<br> Toggle toggle;<br> InputField inputField;<br> <br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-built_in">delegate</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ClickEvent</span>()</span>;<br> <span class="hljs-keyword">public</span> ClickEvent clickEvent;<br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>()</span><br> {<br> <span class="hljs-comment">//1 直接AddListener(string 方法名)</span><br> btn.onClick.AddListener(DoSomething);<br> <span class="hljs-comment">//使用nameof()可以快速定位方法,便于调试,也可以用typeof(),但写起来较麻烦</span><br> btn.onclick.AddListener(<span class="hljs-keyword">nameof</span>(DoSomething));<br> <span class="hljs-comment">//2 Lamda表达式委托 有参</span><br> btn.onClick.AddListener(() =><br> {<br> DoSomething();<br> Debug.Log(<span class="hljs-string">"0"</span>);<span class="hljs-comment">//可以传入更多方法作为参数</span><br> });<br> <span class="hljs-comment">//3 隐式委托</span><br> btn.onClick.AddListener(<span class="hljs-built_in">delegate</span> ()<br> {<br> DoSomething();<br> Debug.Log(<span class="hljs-string">"0"</span>);<br> });<br> <span class="hljs-comment">//4 向委托添加方法</span><br> clickEvent += DoSomething;<br> <span class="hljs-comment">//5 EventTrigger</span><br> EventTrigger trigger = btn.gameObject.GetComponent<EventTrigger>();<br> EventTrigger.Entry entry = <span class="hljs-keyword">new</span> EventTrigger.Entry();<br> entry.eventID = EventTriggerType.PointerClick;<span class="hljs-comment">//鼠标点击事件</span><br> entry.callback = <span class="hljs-keyword">new</span> EventTrigger.TriggerEvent();<br> entry.callback.AddListener(A);<br><br> <span class="hljs-comment">//toggle</span><br> toggle.onValueChanged.AddListener(ToggleAction);<br> toggle.onValueChanged.AddListener(<span class="hljs-built_in">delegate</span> { DoSomething()); });<br> toggle.onValueChanged.AddListener(<span class="hljs-built_in">delegate</span> (<span class="hljs-built_in">bool</span> <span class="hljs-keyword">value</span>) { DoSomething()); });<br> toggle.onValueChanged.AddListener((<span class="hljs-keyword">value</span>) =><br> {<br> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">value</span>)<br> { }<br> <span class="hljs-keyword">else</span> { }<br> });<br><br> <span class="hljs-comment">//InputField</span><br> inputField.onValueChanged.AddListener(<span class="hljs-built_in">delegate</span><br> {<br> DoSomething();<br> });<br> inputField.onEndEdit.AddListener(DoSomethingStr);<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DoSomething</span>()</span> { Debug.Log(<span class="hljs-string">"Do Something"</span>);}<br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DoSomethingStr</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> str</span>)</span> { Debug.Log(str); }<br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">A</span>(<span class="hljs-params">BaseEventData data</span>)</span> { }<br><br> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">ToggleAction</span>(<span class="hljs-params"><span class="hljs-built_in">bool</span> b</span>)</span> { }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>Unity 常用API</title>
<link href="/2024/02/24/Unity-%E5%B8%B8%E7%94%A8API/"/>
<url>/2024/02/24/Unity-%E5%B8%B8%E7%94%A8API/</url>
<content type="html"><![CDATA[<h2 id="Event-Function-事件函数-即生命周期函数"><a href="#Event-Function-事件函数-即生命周期函数" class="headerlink" title="Event Function:事件函数 //即生命周期函数"></a>Event Function:事件函数 //即生命周期函数</h2><p><code>Awake()</code> : 始终在任何 Start 函数之前(开始渲染之前)并在实例化预制件之后(一些manager脚本、网络等)调用此函数。如果游戏对象在启动期间处于非活动状态,则在激活之后才会调用 Awake。<br><code>OnEnable()</code> : 当将物体的SetActive设置为true时就会自动调用调用该方法。<br><code>Awake()</code>、<code>Start()</code> : 都是在游戏物体初始化运行一次,但是Awake的运行顺序高于Start的,并且只要脚本中存在Awake方法,则无论是否挂载了该脚本都会执行该方法。<br><code>Start()</code> :在游戏初始化时会执行一次,不是很紧急的初始化,一般放在Start里面来做。仅在Update函数第一次被调用前调用。<br><code>Fixed Update()</code> : 会按固定时间差重复执行,用在力学更新效果中。执行在Update之前。<br><code>Update()</code> : 每一帧都会运行这个方法,是用于帧更新的主要函数。<br><code>LateUpdate()</code> : 晚于Update的运行顺序,但是FPS和Update是一样的,一般人物的移动放在Update中,而摄像机的跟进变化放到FixedUpdate中。确保两个独立。<br><code>OnDisable()</code> : 物体被禁用时调用。<br><code>OnDestory()</code> : 当对象被销毁或关闭游戏时调用。<br><code>Reset()</code> : 被附加脚本时、在游戏物体的组件上按Reset时会触发该事件函数,调用 Reset 可以在脚本首次附加到对象时以及使用 ReSet 命令时初始化脚本的属性。</p><h2 id="Attribute-属性"><a href="#Attribute-属性" class="headerlink" title="Attribute 属性"></a>Attribute 属性</h2><p><code>[serializeField]</code>:将私有类型和保护类型的变量可视化到面板上<br><code>[System.serializedField]</code>:将自定义类型的变量可视化到面板上<br><code>[HideIninspector]</code>:在面板上隐藏公共变量<br><code>[Header("分组说明")]</code>:将公共变量进行分组<br><code>[Tooltip("提示信息")]</code>:鼠标悬浮在该变量上时显示说明信息<br><code>[Range(float min,float max)]</code>:通过拖动条的方式来控制范围<br><code>[contexMenuItem(string 变量名,方法名())]</code>:停在可视化变量上时显示方法,并可以点击调用,需要是无参数无返回值的方法<br><code>[contexMenu("方法名")]</code>:只为调试,右键选择方法执行<br><code>[Multline(n)]</code>:将字符串设置可见的n行<br><code>[TextArea(min,max)]</code>:添加滚动条来查看设置的文本区<br><code>[DisallowMulipleComponment]</code>:不允许挂载多重脚本</p><h2 id="Directory-路径"><a href="#Directory-路径" class="headerlink" title="Directory 路径"></a>Directory 路径</h2><h2 id="Corsor-鼠标指针"><a href="#Corsor-鼠标指针" class="headerlink" title="Corsor 鼠标指针"></a>Corsor 鼠标指针</h2><ul><li>CursorLockMode.Confined : 将光标限制在游戏窗体中</li><li>CursorLockMode.Locked : 光标锁定到视图的中心</li><li>CuesorLockMode.None : 无规定</li><li>Cursor.visible : 光标可见性</li><li>Input.mousePosition : 当前鼠标在像素坐标中的位置</li></ul><h2 id="Time-时间类函数"><a href="#Time-时间类函数" class="headerlink" title="Time 时间类函数"></a>Time 时间类函数</h2><ul><li>静态变量<ul><li>Time.time :表示从游戏开发到现在的时间,会随着游戏的暂停而停止计算。</li><li>Time.timeSinceLevelLoad : 表示从当前Scene开始到目前为止的时间,也会随着暂停操作而停止。</li><li>Time.deltaTime : 表示从上一帧到当前帧时间,以秒为单位。【一般用来控制角色、动画的运动】</li><li>Time.fixedTime : 表示以秒计游戏开始的时间,固定时间以定期间隔更新(相当于fixedDeltaTime)直到达到time属性。</li><li>Time.fixedDeltaTime : 表示以秒计间隔,在物理和其他固定帧率进行更新,在Edit->ProjectSettings->Time的Fixed Timestep可以自行设置。</li><li>Time.SmoothDeltaTime: 表示一个平稳的deltaTime,根据前 N帧的时间加权平均的值。</li><li>Time.timeScale: 时间缩放,默认值为1,若设置 < 1,表示时间减慢,若设置 > 1,表示时间加快,可以用来加速和减速游戏,回放等、非常有用。如果游戏中控制运动的都是使用了Time.deltatime的话,则可以通过设置Time.timeScale= 0来暂停其运动等。</li><li>Time.frameCount : 总帧数</li><li>Time.realtimeSinceStartup : 表示自游戏开始后的总时间,即使暂停也会不断的增加。【一般用作性能测试】</li><li>Time.captureFramerate : 表示设置每秒的帧率,然后不考虑真实时间。</li><li>Time.unscaledDeltaTime : 以秒计算,完成最后一帧的时间 不考虑timescale时候与deltaTime相同,若timescale被设置,则无效。</li><li>Time.unscaledTime: 从游戏开始到现在所用的时间 不考虑timescale时候与time相同,若timescale被设置,则无效。</li></ul></li></ul><h2 id="GameObject-游戏物体"><a href="#GameObject-游戏物体" class="headerlink" title="GameObject 游戏物体"></a>GameObject 游戏物体</h2><ul><li>创建游戏物体<ul><li>创建空的游戏对象<br><code>new GameObejct("name");</code></li></ul></li><li>实例化创建游戏对象<br><code>public static Object Instantiate (Prefab name);</code>//实例化一个预制件<br><code>public static Object Instantiate (Prefab name,Vector3 position,Quaternion rotation,Transform parent);</code>//并且赋值它的位置、旋转、父物体transform<br>//根据Prefab或者是另外一个游戏物体来创建(克隆Colon),可以实例粒子、等其他的游戏物体,常用<br>通过预制体实例化还可以使用 <code>Resources.Load<GameObject>("PrefabName");</code> 不区分大小写</li><li>创建基本的物体<br><code>CreatPrimitive(PrimitiveType);</code></li><li>添加组件<br><code>new GameObject(name);</code><br><code>name.AddComponent<组件名>();</code><br><code>name.AddComponent<脚本名>();</code></li><li>属性和变量<br><code>object.name</code>:对象的名称。<br><code>GameObject.SetActive(false/true)</code> :通过参数的控制来设置其游戏物体的激活状态,true为激活状态,反之为取消激活状态。<br><code>GameObject.activeInHierarchy</code>: 游戏物体是否处于激活状态,与父类有关,父类被取消激活,则子类也是取消激活的。<br><code>GameObject.activeSelf</code> : 自身的激活状态,与父类无关,只与自身有关。<br><code>GameObject.tag</code>: 游戏物体的tag标签,具体的由程序员自定义设置。</li><li>静态函数,共有方法,变量<br><code>Destroy()</code> :删除游戏物体,但是不会立马在unity中删除,而是会先进行回收,等确定没对象使用的时候,在进行删除<br><code>DontDestroyOnLoad()</code> : 当加载新的场景的时候,不删除这个场景中的某个游戏物体<br><code>FindObjectOfType\<T>()</code> :通过类型T来进行查找对象,返回的是一个对象<br><code>FindObjectsOfType\<T>()</code>:通过类型T来进行查找对象,返回类型为Type的所有活动加载对象的列表。<br><code>FindGameObjectWithTag()</code> :返回标记的Tag活动游戏对象。<br><code>FindGameObjectsWithTag()</code> :返回标记的Tag活动游戏对象列表。如果没有GameObject(游戏物体)返回空数组</li><li>消息发送<br><code>BroadcastMessage()</code> :广播发送消息,则该物体上对应的方法会被调用,同时这个游戏物体上的子物体上对应的方法也会被调用的<br><code>SendMessage()</code>:发送消息,只会对这个游戏物体中脚本上的方法发送消息<br>SendMessageUpwards(): 广播发送消息,但是和BroadcastMessage()是相反的,在调用自身的方法时也会向上传递,调用其父类的方法</li><li>查找组件<br>//1、返回一个对应的组件,如果有多个,则只返回第一个<br><code>Cube cube = target.GetComponent\<Cube>();</code><br>//2、返回该游戏物体上所有符合条件的组件,返回一个组件数组<br><code>Cube[] cc= target.GetComponents\<Cube>();</code><br>//3、返回该游戏物体上的对应组件,同时返回该游戏物体的子类上对应的组件<br><code>Cube[] xx = target.GetComponentsInChildren\<Cube>();</code><br>//4、返回该游戏物体上的对应组件,同时返回该游戏物体的父类上对应的组件<br><code>Cube[] yy = target.GetComponentsInParent\<Cube>();</code></li></ul><h2 id="MonoBehaviours类"><a href="#MonoBehaviours类" class="headerlink" title="MonoBehaviours类"></a>MonoBehaviours类</h2><ul><li>继承的变量成员<br><code>enabled{ get; set; }</code> :返回该组件是否被激活或者是被禁用,可以通过该变量来进行设置<br><code>isActiveAndEnabled{ get; }</code> :只能返回该组件是否激活的标志位,不能设置该变量,为只读的<br><code>tag{ get; set; }</code> :该组件所对应的游戏物体的标签<br><code>transform</code>:附加到此 GameObject 的 Transform。<br><code>name{ get; set; }</code> :该组件所对应的游戏物体的名字</li><li>Invoke(调用)等方法、变量<br>//1、在等待time的时间后调用“方法1”<br><code>Invoke(方法名(),float time);</code><br>//2、返回bool值,如果方法被添加到队列中,但没有被运行则返回true,如果经过一段时间后该方法被调用了则会返回false;<br><code>bool i= IsInvoking("方法1")</code> ;<br>//3、 等待time时间后,会重复开始运行方法1,每秒钟运行number次。<br><code>InvokeRepeating("方法1",time,number);</code><br>//4、会暂停通过Involve/InvokeRepeating的运行,但是一般来说CancelInvoke会和InvokeRepeating组合调用。参数由自己设定<br><code>CancelInvoke();</code></li><li><strong>扩充</strong>:<ul><li>在脚本的类前添加 <code>[ExecuteInEditMode]</code>:则该脚本不用按游戏运行按钮就会开始编译,只限在编辑模式里面</li><li>在脚本的共有变量前添加 <code>[HideInInspector]</code>:则该共有变量不会在Inspector面板进行显示</li></ul></li><li>OnMousexx鼠标触发事件:<br>//如果是通过Collider进行触发检测的话,则要在设置中打开允许进行射线检测。<br><code>OnMouseDown()</code>: 当鼠标按下的时候触发,按一次触发一次<br><code>OnMouseDrag()</code>: 当鼠标按住不放的时候一直触发,是每一帧进行触发<br><code>OnMouseUp()</code>: 当鼠标抬起的时候触发,只执行一次<br><code>OnMouseEnter()</code>: 当鼠标进入的时候触发,进入一次触发一次<br><code>OnMousetOver()</code>: 当鼠标在触发物体的上面时,则一直触发<br><code>OnMouseExit()</code>: 当鼠标移出的时候触发<br><code>OnMouseUpAsButton()</code>: 相当于是按钮的功能,当鼠标在同一个游戏物体上按下抬起的时候才会触发,按下与抬起不在同一个游戏上的话则不会进行触发。</li></ul><h2 id="Debug"><a href="#Debug" class="headerlink" title="Debug"></a>Debug</h2><p><code>Debug.Log("一般日志信息");</code><br><code>Debug.LogWarning("警告信息")</code><br><code>Debug.LogError("错误发生")</code></p><h2 id="Coroutine-协程"><a href="#Coroutine-协程" class="headerlink" title="Coroutine 协程"></a>Coroutine 协程</h2><p>[[笔记/Unity/Unity Coroutine协程|Unity Coroutine协程]]</p><ul><li>定义协程</li></ul><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs C#">IEnumerator 方法名()<br>{<br> <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span> ;<br> <span class="hljs-function"><span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title">WaitForSeconds</span>(<span class="hljs-params"><span class="hljs-number">1.0f</span></span>)</span>; <br> <span class="hljs-comment">//等待一定[[模板/时间|时间]]再运行后面的代码</span><br>}<br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs C#"> <span class="hljs-comment">//通过迭代器定义一个方法</span><br><span class="hljs-function">IEnumerator <span class="hljs-title">Demo</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> i</span>)</span><br>{<br> <span class="hljs-comment">//代码块</span><br> <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; <br> <span class="hljs-comment">//代码块</span><br>}<br><br><span class="hljs-comment">//在程序种调用协程</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Test</span>()</span><br>{<br> <span class="hljs-comment">//第一种与第二种调用方式,通过方法名与参数调用</span><br> StartCoroutine(<span class="hljs-string">"Demo"</span>, <span class="hljs-number">1</span>);<br><br> <span class="hljs-comment">//第三种调用方式, 通过调用方法直接调用</span><br> StartCoroutine(Demo(<span class="hljs-number">1</span>));<br>}<br></code></pre></td></tr></table></figure><ul><li>开启协程<br><code>StartCoroutines(方法名());</code></li><li>开启与关闭协程<br>开启协程:<code>StartCoriutine(参数);</code><br>关闭协程:<code>StopCoroutine(参数);</code><br>其中的参数要互相对应,如果传递的是方法名,则两个方法中的参数就要是方法名<br>如果是IEnumerator的返回值,则其中两个方法发的参数就要是IEnumerator的返回值<br>//1、传递方法名<br>private IEnumerator coroutine;<br>coroutine = WaitAndPrint();<br>StartCoroutine(coroutine);<br>StopCoroutine(coroutine);<br>//2、传递返回值<br>StartCoroutine(“WaitAndPrint”);<br>StopCoroutine(“WaitAndPrint”);</li><li>停止所有的协程<br><code>StopAllCoroutines();</code></li></ul><h2 id="Transform-类"><a href="#Transform-类" class="headerlink" title="Transform 类"></a>Transform 类</h2><h3 id="6-1变量"><a href="#6-1变量" class="headerlink" title="6.1变量"></a>6.1变量</h3><p>GameObject.transform.childCount:父变换具有的子项数。<br>eularAngles:以欧拉角表示的旋转(以度为单位)。<br>forward:Z轴上的位置。<br>right:X轴上的位置。<br>up:Y轴上的位置。<br>localEulerAngles:以欧拉角表示的相对于父变换旋转的旋转(以度为单位)。<br>localPosition:相对于父变换的变换位置。如果变换没有父级,则其与 Transform.position 相同。<br>localRotation:相对于父级变换旋转的变换旋转。<br>localScale:相对于父对象的变换缩放。<br>lossyScale:对象的全局缩放。(只读)<br>parent:变换的父级。更改父级将修改相对于父级的位置、缩放和旋转,但保持世界空间位置、旋转和缩放不变。<br>position:世界空间中的变换位置。<br>root:返回层级视图中最顶层的变换。(永远不返回 null;如果该变换没有父级,则返回自身。)<br>rotation:一个四元数,用于存储变换在世界空间中的旋转。</p><h3 id="6-2公共函数"><a href="#6-2公共函数" class="headerlink" title="6.2公共函数"></a>6.2公共函数</h3><p>DetachChildren:清除所有子项的父级。<br>LookAt(vector3):旋转变换,使向前矢量指向 target 的当前位置。<br>Rotate(vector3);:使用 Transform.Rotate 以各种方式旋转游戏对象。通常以欧拉角而不是四元数提供旋转。<br>RotateAround(vector3 point,vector3 axis,vector3 angle);:将变换围绕穿过世界坐标中的 point 的 axis 旋转 angle 度。<br>SetParent(transform);:设置变换的父级。<br>SetPositionAndRotation:设置变换组件的世界空间位置和旋转。<br>Translate:根据 translation 的方向和距离移动变换。</p><h3 id="6-3继承的成员"><a href="#6-3继承的成员" class="headerlink" title="6.3继承的成员"></a>6.3继承的成员</h3><h4 id="6-3-1变量"><a href="#6-3-1变量" class="headerlink" title="6.3.1变量"></a>6.3.1变量</h4><p>gameObject:此组件附加到的游戏对象。始终将组件附加到游戏对象。<br>tag:此游戏对象的标签。<br>transform:附加到此 GameObject 的 Transform。<br>hideFlags:该对象应该隐藏、随场景一起保存还是由用户修改?<br>name:对象的名称。</p><h4 id="6-3-2公共函数"><a href="#6-3-2公共函数" class="headerlink" title="6.3.2公共函数"></a>6.3.2公共函数</h4><p>BroadcastMessage:调用此游戏对象或其任何子项中的每个 MonoBehaviour 上名为 methodName 的方法。<br>CompareTag:此游戏对象是否使用 tag 进行了标记?<br>GetComponent:如果游戏对象附加了类型为 type 的组件,则将其返回,否则返回 null。<br>GetComponentInChildren:使用深度首次搜索返回 GameObject 或其任何子项中类型为 type 的组件。<br>GetComponentInParent:返回 GameObject 或其任何父项中类型为 type 的组件。<br>GetComponents:返回 GameObject 中类型为 type 的所有组件。<br>GetComponentsInChildren:返回 GameObject 或其任何子项中类型为 type 的所有组件。<br>GetComponentsInParent:返回 GameObject 或其任何父项中类型为 type 的所有组件。<br>SendMessage:调用此游戏对象中的每个 MonoBehaviour 上名为 methodName 的方法。<br>SendMessageUpwards:调用此游戏对象中的每个 MonoBehaviour 上或此行为的每个父级上名为 methodName 的方法。<br>GetInstanceID:返回对象的实例 ID。<br>ToString:返回 GameObject 的名称。</p><h2 id="Mathf-类"><a href="#Mathf-类" class="headerlink" title="Mathf 类"></a>Mathf 类</h2><h3 id="7-1静态变量"><a href="#7-1静态变量" class="headerlink" title="7.1静态变量"></a>7.1静态变量</h3><p>E:表示自然对数的底数,它由常数 e 指定。<br>DegtoRad:度到弧度换算常量(只读)。<br>RadtoDeg:弧度到度换算常量(只读)。<br>Epsilion:微小浮点值(只读)。<br>infinity:正无穷大的表示形式(只读)。<br>NegativeInfinity:负无穷大的表示形式(只读)。<br>PI:众所周知的“3.14159265358979…”值(只读)。[[杂项/圆周率π|圆周率π]]</p><h3 id="7-2静态函数"><a href="#7-2静态函数" class="headerlink" title="7.2静态函数"></a>7.2静态函数</h3><p>Abs() :返回绝对值。<br>approximately:比较两个浮点值,如果它们相似,则返回 true。<br>Ceil() :向上取整的,10.1—>11//CeliTolnt用法相同。<br>Clamp(value,min,max) :如果value的值在min–max之间的话就返回value,<br> 但是如果value的值小于min,则返回min,如果value的值大于max,则返回max,<br> 一般是用在控制角色血量,当玩家的血量减少的时候,不会出现出现低于0和大于100的情况 hp= Mathf.Clamp(hp,0,100);<br>Clamp01:将值限制在 0 与 1 之间并返回值。用于一维柏林噪声函数。<br>ClosePowerOfTwo(value) :取得离value的2次方最近的值<br>DeltaAngle:计算两个给定角度(以度为单位给定)之间的最短差异。<br>DeltaAngke :取得两个角度之间的最小夹角<br>Floor :向下取整//FloorTolnt用法相同。<br>InverseLerp:计算在范围 [a, b] 内生成插值 value 的线性参数 t。<br> a 和 b 值定义线的起点和终点。Value 是 a 与 b 之间的位置。将 a 和 b 以及 value 减去 a 以获得 a’、b’ 和 value’。这会使 a’ 为零,使 b’ 和 value’ 减小。最后将 value’ 除以 b’。这可获得 InverseLerp 量。<br> 可用于进度条显示。<br>IsPowerOfTwo:如果值是 2 的幂,则返回 true。<br>Lerp:在 a 与 b 之间按 t 进行线性插值。<br>Log:返回指定的数字以指定的底数为底的对数。<br>Log10:返回指定的数字的以 10 为底的对数。<br>Max:返回两个或更多值中的最大值。<br> // public static int Max (params int[] values);<br> Min:很明显是用来返回最小值的。<br>MoveTowards:将值 current 向 target 靠近。<br> // Mathf.MoveTowards(currStrength, maxStrength, recoveryRate * Time.deltaTime);<br>PerlinNoise:生成 2D 柏林噪声。<br>Pow(i,j) :取得i的j次方。<br>PingPong(t,maxValue) :类似乒乓球的来回运动,起始 值是0,通过t变量来控制值由0向maxValue移动,当t大于maxValue的时候又向0进行移动,然后就这样的来回往复运动,一般t变量用时间Time.deltatime来进行控制的。<br>Round:返回舍入为最近整数的 /f/。满0.5进一。<br>Sign(f):返回f的正负号。<br>Sqrt(f):返回 f 的平方根。</p><h2 id="Input-输入"><a href="#Input-输入" class="headerlink" title="Input 输入"></a>Input 输入</h2><p>GetKey() :按键一直按着时触发。<br>GetKeyDown():按键被按下那一刻进行触发。<br>GetKeyUp() :按键被按下后抬起时触发。</p><p>GetMouseButton(0/1/2):1:左键 2:右键 3:中键 鼠标一直按着时触发。<br>GetMouseButtonDown():鼠标按下那一刻触发。<br>GetMouseButtonUp():鼠标抬起的那一刻时触发。</p><p>GetButtonDown():键盘按钮按下那一刻触发。<br>GetButton():键盘按钮抬起的那一刻时触发。<br>GetButtonUp():键盘按钮抬起的那一刻时触发。</p><p>GetAxis(“虚拟轴名”):通过按下的虚拟轴来返回-1~1之间的值,开始值是0,然后向-1/1进行渐渐的变化,有一定的加速度。一般用来控制运动的,比如是赛车的加速运动等。<br>GetAxisRaw() :其他的和GetAxis差不多,就是少了渐变效果,返回值只有 0 1 -1三个。</p><p>anyKeyDown{get;} :当任何按键被按下(包括鼠标按键)时返回true。<br>anyKey{get;} :当任何按键被按着(包括鼠标)时返回true。<br>mousePosition{get;} :返回鼠标在屏幕上的像素坐标,【屏幕坐标】z轴衡为0的。</p><h2 id="Vector2:二维向量"><a href="#Vector2:二维向量" class="headerlink" title="Vector2:二维向量"></a>Vector2:二维向量</h2><p>//public Vector2 (float x, float y);<br>magnitude{get;} :返回向量的长度。<br>normalized{get;} :返回这个向量长度为1的矢量,不管这个向量多长,也是返回1的矢量,只是返回值,不对原向量的值产生影响。<br>Normalize() :无参数的,也是向量化,但是调用该方法会改变原向量值,使其的值被向量化 了。<br>ClampMagnitude() :将一个向量限制在参数中指定的长度之间。<br>MoveToWards() :用来做匀速的运动,由一个位置向另一个位置进行移动。<br>sqrMagnitude{get;} : 对求向量的的长度时不进行开平方根运算了,减少性能的损耗,一般是用来比较两个向量的长度大小的。<br> 扩充:向量是结构体,为值类型,修改其中的变量的时候要整体进行修改,不能单独的进行单个变量的赋值修改。</p><h2 id="Vector3:三维变量"><a href="#Vector3:三维变量" class="headerlink" title="Vector3:三维变量"></a>Vector3:三维变量</h2><p>//public Vector3 (float x, float y, float z);<br>Cross() :插乘运算【左手法则】,通过两个向量来获得另一个向量的方向,然后进行相关的判断。<br>Project() :投影运算。<br>Reflect() :反射运算。<br>Slerp() :按照角度进行插值,与lerp的按照位置信息进行插值的,一般用在炮台的旋转,使旋转的更加平滑。<br>Distence(a,b):返回float a和b之间的距离</p><h2 id="Random随机数类"><a href="#Random随机数类" class="headerlink" title="Random随机数类"></a>Random随机数类</h2><h3 id="静态函数"><a href="#静态函数" class="headerlink" title="静态函数"></a>静态函数</h3><ul><li><code>InitState</code>:通过参数指定的种子随机化生成器的状态,然后再调用Range()产生随机数的时候会依据种子来进行生成,则每一次运行所生成的随机数都是一样的,是伪随机数。一般要生成的随机数不同,可以设置参数System.DataTime.Now.Ticks:通过时间戳来完成。</li><li><code>Range(min,max)</code> :返回一个 在最小值(包括)和最大值(包括)之间的浮点型随机数(只读)。</li></ul><h3 id="静态变量"><a href="#静态变量" class="headerlink" title="静态变量"></a>静态变量</h3><ul><li><code>insideUnitFCircle</code> :返回一个单位圆内的随机点(只读)。</li><li><code>insideUnitSphere</code> :返回单位球内的一个随机点(只读)。</li><li><code>onUnitSphere</code>:返回单位球表面上的一个随机点(只读)。</li><li><code>rotation</code> :返回随机旋转。</li><li><code>rotationUniform</code> :返回具有一致分布的随机旋转。</li><li><code>state</code> :获取或设置随机数生成器的完整内部状态。</li><li><code>value</code> :返回一个在[0.0,1.0]范围内的随机值(只读)。</li></ul><h3 id="System-Random"><a href="#System-Random" class="headerlink" title="System.Random"></a>System.Random</h3><h4 id="构造函数"><a href="#构造函数" class="headerlink" title="构造函数"></a>构造函数</h4><ul><li><code>Random();</code>//使用默认种子值(系统时间的毫秒值)初始化 Random 类的新实例。</li><li><code>Random(Int32);</code>//使用指定的种子值初始化 Random 类的新实例。<ul><li>由于Random在不给定随机种子的情况下是使用系统当前时间刻作为随机种子,所以在运行速度较快时,容易生成重复结果,此时可以使用该方法生成不会重复的随机种子: <code>int RandomSeed=BitConverter.ToInt32(Guid.NewGuid().ToByteArray());</code> 。</li></ul></li></ul><h4 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h4><ul><li><code>Next();</code>//每次产生一个不同的随机正整数</li><li><code>Next(int max Value);</code>//产生一个比 max Value(2,147,483,647) 小的正整数</li><li><code>Next(int min Value,int max Value);</code>//产生一个 minValue~maxValue 的正整数,但不包含 maxValue</li><li><code>NextDouble();</code>//产生一个0.0~1.0的浮点数</li><li><code>NextBytes(byte[]);</code>//用随机数填充指定字节数的数组(0-255)</li></ul><h2 id="Quaternion-四元数"><a href="#Quaternion-四元数" class="headerlink" title="Quaternion 四元数"></a>Quaternion 四元数</h2><p>欧拉角【eylarAngles】与面板中的值对应和四元数【rotation】之间是可以进行转换的,一般欧拉角是用来让用户可以直观的看到的,而四元数是用来控制内部的运算 的。<br>eulerAngles :将四元数转变为欧拉角<br>Euler() :将欧拉角转变为四元数<br>LookRotation() :让玩家通过设置四元数来进行望向敌人的旋转,将向量方向转变为四元数<br>slerp() :在做朝向的旋转的时候,不建议使用lerp,而是建议使用slerp,使其的旋转朝向更为平滑,更加的自然</p><h2 id="Rigidbody:刚体组件,控制物体的移动"><a href="#Rigidbody:刚体组件,控制物体的移动" class="headerlink" title="Rigidbody:刚体组件,控制物体的移动"></a>Rigidbody:刚体组件,控制物体的移动</h2><p>[[笔记/Unity/Unity 移动物体的方式|Unity 移动物体的方式]]里有一些常见的Rigidbody用法<br>AddForce() :添加到刚体的力。<br>AddExplosionForce() :应用一个力到刚体来模拟爆炸效果。<br>AddForceAtPosition() :在position位置应用force力。作为结果这个将在这个物体上应用一个扭矩和力。<br>AddRelativeForce() :添加力到刚体。相对于它的系统坐标。<br>AddRelativeTorque(vector3) :相对于它的局部坐标系统添加扭矩到刚体。<br>AddTorque(vector3) :添加扭矩到刚体。<br>ClosestPointOnBounds() :指定位置到该刚体附加的碰撞器的最近点。<br>GetPointVelocity() :刚体在世界坐标空间,worldPoint点的速度。<br>GetRelativePointVelocity() :相对于刚体在relativePoint点的速度。<br>IsSleeping() :是否正休眠<br>MovePosition() :移动位置,对position的优化,其中利用了插值运算,一般持续运动的则使用这个方法,不出现卡顿的现象.<br>MoveRotation() :移动角度,用来控制刚体的旋转,一般不建议使用rotation,比较耗性能,建议使用MoveRotation(),然后配合Quaternion,slerp()进行使用,使其更加的平滑.<br>ResetCenterOfMass() :重置刚体的质心。<br>ResetInertiaTensor() :重置惯性张量值和旋转。<br>Rigidbody.position: 可以通过刚体来控制运动,在控制运动方面,使用rigibody.positon比transform.porition计算要快的多,相关的物理计算也是在刚体中计算好了,但是不建议使用这个方法来持续的控制物体的运动,不平滑,控制一两次的时候还可以使用<br>SetDensity() :设置基于附加的碰撞器假设一个固定的密度质量。<br>Sleep() :强制刚体休眠。<br>SweepTest() :如果一个刚体碰到任何东西触发测试。<br>SweepTestAll() :就像Rigidbody.SweepTest,当返回的是所有碰撞信息。<br>WakeUp() :强制一个刚体唤醒。</p><h2 id="Collision-碰撞体"><a href="#Collision-碰撞体" class="headerlink" title="Collision 碰撞体"></a>Collision 碰撞体</h2><p>变量</p><p> articulationBody | The ArticulationBody of the collider that your GameObject collides with (Read Only).<br>body:The Rigidbody or ArticulationBody of the collider that your Component collides with (Read Only).<br>collider:我们撞击的 Collider(只读)。<br>contactCount:获取此碰撞的接触点数。<br>contacts: 物理引擎生成的接触点。应避免使用它,因为它会产生内存垃圾。改用 GetContact 或 GetContacts。<br>gameObject:您正在碰撞其碰撞体的 GameObject。(只读)。<br>impulse:为解析此碰撞而施加于该接触对的总冲量。<br>relativeVelocity:这两个碰撞对象的相对线性速度(只读)。<br>rigidbody:我们撞击的 Rigidbody(只读)。如果我们撞击的对象未附加刚体,则这是 /null/。<br>transform:我们撞击的对象的 Transform(只读)。</p><p>Collider.OnCollisionEnter : 碰撞体进入碰撞范围<br>Collider.OnCollisionStay : 碰撞体停留<br>Collider.OnCollisionExit : 碰撞体脱离碰撞体</p><h2 id="Camera-相机组件"><a href="#Camera-相机组件" class="headerlink" title="Camera 相机组件"></a>Camera 相机组件</h2><p>Camera是一个设备,玩家通过它看世界。<br>屏幕空间点用像素定义,屏幕的左下为(0,0);右上是(PixelWidth,pixelHeight).Z的位置是以世界单位衡量的到相机的距离。<br>视口空间点是规范的并相对于相机的。相机的左下为(0,0);右上是(1,1);Z的位置是以世界为单位衡量的到相机的距离。<br>Ray ray = cameraMain.ScreenPointToRay(Input.mousePosition); //获得相机到鼠标之间的射线<br>RaycastHit hit; //用来存放射线检测到的游戏物体的信息的<br>bool temp = Physics.Raycast(ray, out hit); //进行射线检测<br>CalculateObliqueMatrix() :计算并返回倾斜接近水平的投影矩阵。<br>CopyFrom() :使这个相机的设置与其他相机相同。<br>Render() :手动渲染相机。<br>RenderToCubemap() :从这个相机渲染到一个立方贴图。<br>RenderWithShader() : 用shader替代渲染相机。<br>ResetAspect() :恢复长宽比为屏幕的长宽比。<br>ResetProjectionMatrix() :让投影反映正常的相机参数。<br>ResetReplacementShader() :从相机上移除shader替换。<br>ResetWorldToCameraMatrix() :在场景中让渲染位置反映相机的位置<br>ScreenPointToRay() :返回一条射线从摄像机通过一个屏幕点。<br>ScreenToViewportPoint() :从屏幕空间到视窗空间的变换位置。<br>ScreenToWorldPoint() :从屏幕空间到世界空间的变化位置。<br>SetReplacementShader() :使相机渲染用shader替换。<br>SetTargetBuffers() :设置相机渲染到一个或多个RenderTextures所选择的缓冲区。<br>ViewportPointToRay() :返回从相机出发穿过视点的一个射线。<br>ViewportToScreenPoint() :从视口空间到屏幕空间的变换位置。<br>ViewportToWorldPoint() :从视窗空间到世界空间的变换位置。<br>WorldToScreenPoint() :从世界空间到屏幕空间变换位置。<br>WorldToViewportPoint() :从世界空间到视窗空间的变换位置。</p><h2 id="Application-程序"><a href="#Application-程序" class="headerlink" title="Application 程序"></a>Application 程序</h2><p><code>OpenURL("www.baidu.com")</code> :打开指定的网址<br>Application.Quit() :退出游戏的运行<br>CapturScreenshot(“游戏截图”) : 用来截图的,字符串为截图fileName<br><code>Application.streamingAssetsPath</code>:这个属性用于返回流数据的缓存目录,返回路径为相对路径,适合设置一些外部数据文件的路径。在Unity工程的Assets目录下起一个名为“StreamingAssets”的文件夹即可,然后用Application.streamingAssetsPath访问,这个文件夹中的资源在打包时会原封不动的打包进去,不会压缩,一般放置一些资源数据。在PC/MAC中可实现对文件的“增删改查”等操作,但在移动端是一个只读路径。</p><h2 id="SceneManager-场景类"><a href="#SceneManager-场景类" class="headerlink" title="SceneManager 场景类"></a>SceneManager 场景类</h2><p>LoadScene() :加载下一个场景,一般是用在另一个场景不是太大的情况下<br>LoadSceneAsync() :异步加载下一个场景,返回AsyncOperation类型,里面包含了加载的信息,加载的进度条等等。可以让用户缓解等待加载场景的时间<br>sceneCount : 获得当前加载的场景个数<br>sceneCountInBuildSettings :在Build面板中加载的场景个数<br>GetActiveScene() : 获取已经加载的当前场景的信息<br>GetSceneAt(index) : 加载index索引的场景</p><p>当加载新的场景的时候会触发下面的事件:<br>activeSceneChanged :当有新场景被加载的时候就会调用这个事件<br>sceneLoaded :当有新场景加载完成的时候就会触发这个事件<br> //事件的注册时通过加方法来进行注册的:<br>SceneManger.activeSceneChanged+=OnAcitiveScenenChanged;</p><h2 id="Ray-射线"><a href="#Ray-射线" class="headerlink" title="Ray 射线"></a>Ray 射线</h2><p>//一般射线检测要在射线检测的范围内,并且被检测物体要有Collider<br>direction :射线的方向。<br>origin :射线的原点。<br>Ray :创建一条射线从origin开始,沿direction方向。<br>//public Ray (Vector3 origin, Vector3 direction);<br>Raycast;检测的是射线碰撞到的第一个物体,不具有穿透性<br>RaycastAll:返回的是RaycastHit数组,具有穿透性,可以返回检测到的多个游戏物体<br>RaycastHit hit; //存储射线检测到的游戏物体信息<br>PaycastHit hit;//hit中存放的是射线检测的碰撞信息</p><h2 id="WWW-类"><a href="#WWW-类" class="headerlink" title="WWW 类"></a>WWW 类</h2><p>//下载 是用来在网络中下载资源的<br>WWW :用给定的URL创建一个WWW请求。<br>GetAudioClip() :从下载数据,返回一个AudioClip(只读)。<br>LoadImageIntoTexture() :利用一个从下载数据中的图像来替换现有Texture2D。<br>LoadUnityWeb() :加载新的web播放器数据文件。</p><h2 id="GUI-现已废弃,使用unity自带UI-UGUI"><a href="#GUI-现已废弃,使用unity自带UI-UGUI" class="headerlink" title="GUI //现已废弃,使用unity自带UI(UGUI)"></a>GUI //现已废弃,使用unity自带UI(UGUI)</h2><p>静态函数<br>BeginGroup:开始一个组。必须与 EndGroup 调用配对使用。//public static void BeginGroup (Rect position, string text);<br>EndGroup:结束组。<br>BeginScrollView:在 GUI 内开始一个滚动视图。//public static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect);<br>EndScrollView:结束使用 BeginScrollView 调用开始的滚动视图。<br>Box在 :GUI 层上创建一个框。//public static void Box (Rect position, string text);<br>BringWindowToBack:将特定窗口放置到该浮动窗口的后方。<br>BringWindowToFront:将特定窗口放置到该浮动窗口的前方。<br>Button:创建一个单击按钮。当用户点击该按钮时,立即执行一些操作。//public static bool Button (Rect position, string text);<br>DragWindow:使窗口可被拖动。//public static void DragWindow (Rect position);<br>FocusControl:将键盘焦点移动到某个命名控件。<br>FocusWindow:使某个窗口成为激活窗口。<br>HorizontalScrollbar:创建一个水平滚动条。滚动条是用于滚动文档的控件。大多数情况下,您需要的可能是滚动视图。<br>//public static float HorizontalScrollbar (Rect position, float value, float size, float leftValue, float rightValue);<br>HorizontalSlider:用户可以拖动的水平滑动条,用于在最小值和最大值之间更改某值。<br>//public static float HorizontalSlider (Rect position, float value, float leftValue, float rightValue);<br>Label:在屏幕上创建一个文本或纹理标签。//public static void Label (Rect position, string text);<br>ModalWindow:显示一个模态窗口。<br>ScrollTo:滚动包含的所有滚动视图,让它们尝试使 position 可见。//public static void ScrollTo (Rect position);<br>SelectionGrid:创建一个按钮网格。//public static int SelectionGrid (Rect position, int selected, string[] texts, int xCount);<br>TextArea:创建一个可供用户编辑字符串的多行文本区域。//public static string TextArea (Rect position, string text);<br>TextField:创建一个可供用户编辑字符串的单行文本字段。//public static string TextField (Rect position, string text);<br>Toggle:创建一个打开/关闭的开关按钮。//public static bool Toggle (Rect position, bool value, string text);<br>Toolbar:创建一个工具栏。//public static int Toolbar (Rect position, int selected, string[] texts);<br>VerticalScrollbar:创建一个垂直滚动条。滚动条是用于滚动文档的控件。大多数情况下,您需要的可能是滚动视图。<br>//public static float VerticalScrollbar (Rect position, float value, float size, float topValue, float bottomValue);<br>VerticalSlider:用户可以拖动的垂直滑动条,用于在最小值和最大值之间更改某值。<br>//public static float VerticalSlider (Rect position, float value, float topValue, float bottomValue);<br>Window:创建一个弹出窗口。//public static Rect Window (int id, Rect clientRect, GUI.WindowFunction func, string text);</p><h2 id="Rect-矩形"><a href="#Rect-矩形" class="headerlink" title="Rect 矩形"></a>Rect 矩形</h2><p>构造矩形。//public Rect (float x, float y, float width, float height);<br>通过最小/最大坐标值创建矩形。//public static Rect MinMaxRect (float xmin, float ymin, float xmax, float ymax);</p>]]></content>
<tags>
<tag>Unity</tag>
</tags>
</entry>
<entry>
<title>匈牙利记号法</title>
<link href="/2024/02/24/%E5%8C%88%E7%89%99%E5%88%A9%E8%AE%B0%E5%8F%B7%E6%B3%95/"/>
<url>/2024/02/24/%E5%8C%88%E7%89%99%E5%88%A9%E8%AE%B0%E5%8F%B7%E6%B3%95/</url>
<content type="html"><![CDATA[<p>有关项目的全局变量用 <code>g_</code> 开始,类的成员变量用 <code>m_</code> ,局部变量若函数较大可考虑用 <code>l_</code> 说明其是局部变量</p><table><thead><tr><th>前缀</th><th>类型</th><th>说明</th></tr></thead><tbody><tr><td>a_</td><td>Array</td><td>数组</td></tr><tr><td>b_</td><td>bool(int)</td><td>布尔(整数)</td></tr><tr><td>by_</td><td>Unsigned Char(byte)</td><td>无符号字符(字节)</td></tr><tr><td>c</td><td>char</td><td>字符(字节)</td></tr><tr><td>cb</td><td>Count of Bytes</td><td>字节数</td></tr><tr><td>cr</td><td>Color Reference Value</td><td>颜色(参考)值</td></tr><tr><td>cx</td><td>Count of X(short)</td><td>x的集合(短整数)</td></tr><tr><td>f</td><td>Flags(Usually mutiple bit values)</td><td>标志(一般是多位数的数值)</td></tr><tr><td>fn</td><td>Function</td><td>函数</td></tr><tr><td>g_</td><td>global</td><td>全局</td></tr><tr><td>h</td><td>Handle</td><td>句柄</td></tr><tr><td>i</td><td>Integer</td><td>整数</td></tr><tr><td>l</td><td>long</td><td>长整数</td></tr><tr><td>lp</td><td>Long Pointer</td><td>长指针</td></tr><tr><td><strong>m_</strong></td><td>Data Menber of a Class</td><td><strong>一个类的数据成员</strong></td></tr><tr><td>n</td><td>short Integer</td><td>短整数</td></tr><tr><td>p</td><td>Pointer</td><td>指针</td></tr><tr><td>s</td><td>String</td><td>字符串</td></tr><tr><td>sz</td><td>Zero Terminated String</td><td>以零结束的字符串</td></tr><tr><td>tm</td><td>Text Metric</td><td>文本规则</td></tr><tr><td>u</td><td>Unsigned Integer</td><td>无符号整数</td></tr><tr><td>ul</td><td>Unsigned Long(Ulong)</td><td>无符号长整数</td></tr><tr><td>w</td><td>WORD(Unsigned Short)</td><td>无符号短整数</td></tr><tr><td>x,y</td><td>x,y Coordinates(Short)</td><td>坐标值(短整数)</td></tr><tr><td>v</td><td>Void</td><td>空</td></tr></tbody></table>]]></content>
</entry>
<entry>
<title>驼峰命名法</title>
<link href="/2024/02/24/%E9%A9%BC%E5%B3%B0%E5%91%BD%E5%90%8D%E6%B3%95/"/>
<url>/2024/02/24/%E9%A9%BC%E5%B3%B0%E5%91%BD%E5%90%8D%E6%B3%95/</url>
<content type="html"><![CDATA[<p>简介:混合使用大小写字母来构成变量和函数的名称。<br>意义:提高代码的可读性,便于项目开发和维护。</p><ul><li>大驼峰法:<ul><li>规则:<strong>第一个单词和其他单词的首字母均大写。</strong></li><li>用于:<em><strong>类名</strong></em>、<em><strong>函数名</strong></em>、<em><strong>属性</strong></em>、<em><strong>命名空间</strong></em>。</li></ul></li><li>小驼峰法:<ul><li>规则:<strong>除第一个单词外,其他单词首字母均大写。</strong></li><li>用于:<em><strong>变量</strong></em>。</li></ul></li></ul>]]></content>
</entry>
<entry>
<title>Hexo Front-matter</title>
<link href="/2024/02/21/Hexo-Front-matter/"/>
<url>/2024/02/21/Hexo-Front-matter/</url>
<content type="html"><![CDATA[<h2 id="可用的文章属性"><a href="#可用的文章属性" class="headerlink" title="可用的文章属性"></a>可用的文章属性</h2><table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td>layout</td><td>布局</td><td>config.default_layout</td></tr><tr><td>title</td><td>标题</td><td>文章的文件名</td></tr><tr><td>date</td><td>建立日期</td><td>文件建立日期</td></tr><tr><td>update</td><td>更新日期</td><td>文件更新日期</td></tr><tr><td>comments</td><td>开启文章的评论功能</td><td>true</td></tr><tr><td>tags</td><td>标签(不适用于分页)</td><td></td></tr><tr><td>categories</td><td>分类(不适用于分页)</td><td></td></tr><tr><td>permalink</td><td>覆盖文章的永久链接</td><td>null</td></tr><tr><td>excerpt</td><td>纯文本的页面摘要</td><td></td></tr><tr><td>disableNunjucks</td><td>禁用Nunjucks标签 <code>{{}}}</code>/<code>{% %}</code>和标签插件的渲染功能</td><td>false</td></tr><tr><td>lang</td><td>设置语言以覆盖自动检测</td><td></td></tr><tr><td>published</td><td>文章是否发布</td><td>post下的文章为true,draft下的文章给你为false</td></tr></tbody></table><h2 id="典型的分类和标签形式如下"><a href="#典型的分类和标签形式如下" class="headerlink" title="典型的分类和标签形式如下"></a>典型的分类和标签形式如下</h2><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-meta">---</span><br><span class="hljs-attr">categories:</span><br><span class="hljs-bullet">-</span> <span class="hljs-string">diary</span><br><span class="hljs-attr">tags:</span><br><span class="hljs-bullet">-</span> <span class="hljs-string">PS3</span><br><span class="hljs-bullet">-</span> <span class="hljs-string">Games</span><br><span class="hljs-meta">---</span><br></code></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title>死循环</title>
<link href="/2024/02/21/%E6%AD%BB%E5%BE%AA%E7%8E%AF/"/>
<url>/2024/02/21/%E6%AD%BB%E5%BE%AA%E7%8E%AF/</url>
<content type="html"><![CDATA[<h1 id="死循环"><a href="#死循环" class="headerlink" title="死循环"></a>死循环</h1><h2 id="以无限循环的形式实现监听守护"><a href="#以无限循环的形式实现监听守护" class="headerlink" title="以无限循环的形式实现监听守护"></a>以无限循环的形式实现监听守护</h2><p><code>for (; ; )</code> 死循环(Infinite Loop)</p><p>这种写法通常用于需要持续运行或监听某些事件的场景,例如服务器端的消息监听、守护线程的执行等。在使用死循环时,需要谨慎处理循环体内部的逻辑,确保循环能够在适当的时候退出,避免陷入无限循环造成系统资源的浪费或程序无法正常终止。要注意的是,在某些情况下,编译器或代码静态分析工具可能会提示无限循环的警告或错误,因为这种写法可能会引起程序不可达的问题。因此,在使用死循环时,需要确保循环终止的条件是正确设置和处理的。在循环内使用 <code>continue;</code> 和 <code>break;</code> 控制循环条件。类似于 <code>While(true)</code> 。</p>]]></content>
</entry>
<entry>
<title>判断浮点数是否相等</title>
<link href="/2024/02/21/%E5%88%A4%E6%96%AD%E6%B5%AE%E7%82%B9%E6%95%B0%E6%98%AF%E5%90%A6%E7%9B%B8%E7%AD%89/"/>
<url>/2024/02/21/%E5%88%A4%E6%96%AD%E6%B5%AE%E7%82%B9%E6%95%B0%E6%98%AF%E5%90%A6%E7%9B%B8%E7%AD%89/</url>
<content type="html"><![CDATA[<h1 id="关于浮点数判断时的误差问题"><a href="#关于浮点数判断时的误差问题" class="headerlink" title="关于浮点数判断时的误差问题"></a>关于浮点数判断时的误差问题</h1><p>在做关于浮点数的计算时,不要使用 <code>==</code> 来做判断,因为无法避免误差。</p><p>不要使用:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-keyword">var</span> testresult:<span class="hljs-built_in">float</span> = <span class="hljs-number">1</span> - <span class="hljs-number">0.8f</span>;<br><span class="hljs-keyword">if</span>(testresult == <span class="hljs-number">0.2f</span>)<br>{<br>Debug.Log(message:<span class="hljs-string">"equal"</span>);<br>}<br><span class="hljs-keyword">else</span><br>{<br>Debug.Log(message:<span class="hljs-string">"not equal"</span>);<br>}<br></code></pre></td></tr></table></figure><p>而是:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-built_in">bool</span> <span class="hljs-title">WithinErroeMargin</span>(<span class="hljs-params"><span class="hljs-built_in">float</span> left, <span class="hljs-built_in">float</span> right</span>)</span><br>{<br><span class="hljs-keyword">return</span> Mathf.Abs.(f: left = right) <= <span class="hljs-number">0.0001f</span>;<span class="hljs-comment">//误差范围0.0001f,根据使用场景而定</span><br>}<br><span class="hljs-keyword">if</span>(WithinErrorMargin(left: testresult, right: <span class="hljs-number">0.2f</span>))<br>{<br>Debug.Log(message:<span class="hljs-string">"WithinErrorMargin equal"</span>);<br>}<br><span class="hljs-keyword">else</span><br>{<br>Debug.Log(message:<span class="hljs-string">"WithinErrorMargin not equal"</span>);<br>}<br></code></pre></td></tr></table></figure><p>当需要浮点数转换时,尽量避免强制转换产生的精度丢失,常用的库有:</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs C#"><span class="hljs-built_in">bool</span> equal = Mathf.Approximately(<span class="hljs-number">1.0f</span>, <span class="hljs-number">10.0f</span> / <span class="hljs-number">10.0f</span>);<br><span class="hljs-comment">//该判断的误差范围接近无穷小</span><br></code></pre></td></tr></table></figure><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs C#">Mathf.RoundToInt(f:<span class="hljs-number">1.9f</span>);<span class="hljs-comment">//2 返回最接近1.9的整数 四舍五入 </span><br>Mathf.FloorToInt(f:<span class="hljs-number">1.9f</span>);<span class="hljs-comment">//1 返回小于等于1.9的最大整数 向下取整</span><br>Mathf.CeliToInt(f:<span class="hljs-number">1.9f</span>);<span class="hljs-comment">//2 返回大于等于1.9的最小整数 向上取整</span><br></code></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title>高内聚低耦合</title>
<link href="/2024/02/21/%E9%AB%98%E5%86%85%E8%81%9A%E4%BD%8E%E8%80%A6%E5%90%88/"/>
<url>/2024/02/21/%E9%AB%98%E5%86%85%E8%81%9A%E4%BD%8E%E8%80%A6%E5%90%88/</url>
<content type="html"><![CDATA[<h1 id="高内聚低耦合"><a href="#高内聚低耦合" class="headerlink" title="高内聚低耦合"></a>高内聚低耦合</h1><h2 id="高内聚"><a href="#高内聚" class="headerlink" title="高内聚"></a>高内聚</h2><p>高内聚是另外一个评判软件设计质量的标准。内聚更为专业的说法叫做功能内聚,是对系统中元素职责的相关性和集中度的量度。如果元素有高度的相关职责,除了这些职责在没有其他的工作,那么该元素就有高内聚。<br>内聚指的是模块内部的功能,最强的就是功能不能拆分,也就是原子化。</p><h3 id="例如"><a href="#例如" class="headerlink" title="例如"></a>例如</h3><p>这就好像,如果我是一个项目经理,我的职责是监控和协调我的项目各个阶段的工作。当我的项目进入需求分析阶段,我会请求需求分析员来完成;当我的项目进入开发阶段,我会请求软件开发人员来完成;当我的项目需要测试的时候,我会请求测试人员……如果我参与了开发,我就不是一个高内聚的元素,因为开发不是我的职责。</p><h3 id="为什么要高内聚"><a href="#为什么要高内聚" class="headerlink" title="为什么要高内聚"></a>为什么要高内聚</h3><ul><li>可读性</li><li>复用性</li><li>可维护性和易变更性</li></ul><h2 id="低耦合"><a href="#低耦合" class="headerlink" title="低耦合"></a>低耦合</h2><p>耦合就是元素与元素之间的连接,感知和依赖量度。这里说的元素即是功能,对象,系统,子系统。模块。</p><h3 id="例如-1"><a href="#例如-1" class="headerlink" title="例如"></a>例如</h3><p>现在有方法A和方法B<br>我们在A元素去调用B元素,当B元素有问题或者不存在的时候,A元素就不能正常的工作,那么就说元素A和元素B耦合</p><h3 id="耦合带来的问题"><a href="#耦合带来的问题" class="headerlink" title="耦合带来的问题"></a>耦合带来的问题</h3><p>当元素B变更或者不存在时,都将影响元素A的正常运作,影响系统的可维护性和易变更性。同时元素A只能运行在元素B中,这也大大的降低了A元素的可复用性。正因为耦合的种种弊端,我们才需要在软件设计上追求低耦合</p><h3 id="如何实现低耦合"><a href="#如何实现低耦合" class="headerlink" title="如何实现低耦合"></a>如何实现低耦合</h3><ul><li>元素A不能过度依赖元素B</li><li>合理的职责划分:让系统中的对象各司其职,不仅是提高内聚的要求,同时也可以有效地降低耦合</li><li>使用接口而不是继承:我们不难发现。继承就是一种耦合,假如子类A继承了父类B,不论是直接继承或者间接继承,一但父类B不存在或者发生任何变更,都将导致子类A不得不修改或者重写。假如父类B的子类数十上百的,这就是灾难性的变更。</li></ul>]]></content>
</entry>
<entry>
<title>建站纪念</title>
<link href="/2024/02/21/%E5%BB%BA%E7%AB%99%E7%BA%AA%E5%BF%B5/"/>
<url>/2024/02/21/%E5%BB%BA%E7%AB%99%E7%BA%AA%E5%BF%B5/</url>
<content type="html"><![CDATA[<h1 id="建站纪念"><a href="#建站纪念" class="headerlink" title="建站纪念"></a>建站纪念</h1><p>从昨天的半夜一置到凌晨5点,折腾了半天终于用hexo把hithub个人主页给弄出来了。<br>之前用github默认的jekyll模板建过主页,导致hexo建站push不上去,git成功但是主页没变。<br>之后直接删库,重新建了一个username.github.io,又重新push了一次,这次成功了,而且也不用像jekyll那样,DeployAction之后还得等几分钟。<br>只要hexo generate之后hexo deploy上去就更新完成了。确实是非常方便,而且我用了fluid主题,文档非常丰富,之后肯定还会继续更新和丰富博客。</p>]]></content>
</entry>
<entry>
<title>Hello World</title>
<link href="/2024/02/21/hello-world/"/>
<url>/2024/02/21/hello-world/</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post-创建新post"><a href="#Create-a-new-post-创建新post" class="headerlink" title="Create a new post 创建新post"></a>Create a new post 创建新post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo new <span class="hljs-string">"My New Post"</span><br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server-运行服务"><a href="#Run-server-运行服务" class="headerlink" title="Run server 运行服务"></a>Run server 运行服务</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo server<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files-生成固定文档"><a href="#Generate-static-files-生成固定文档" class="headerlink" title="Generate static files 生成固定文档"></a>Generate static files 生成固定文档</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo generate<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites-部署到远程站点"><a href="#Deploy-to-remote-sites-部署到远程站点" class="headerlink" title="Deploy to remote sites 部署到远程站点"></a>Deploy to remote sites 部署到远程站点</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo deploy<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
</entry>
</search>