主頁 > 後端開發 > go A*尋路筆記

go A*尋路筆記

2023-02-27 07:31:30 後端開發

1 func absInt(x int) int {
2     if x < 0 {
3         return -x
4     }
5     return x
6 }

下面會用到此方法, int型別值取絕對值

 

 1 type sp_item struct {
 2     x int
 3     y int
 4     g int
 5     h int
 6     f int
 7     p *sp_item
 8 }
 9 
10 type sp_open []*sp_item
11 
12 func (sp sp_open) Len() int {
13     return len(sp)
14 }
15 
16 func (sp sp_open) Less(i, j int) bool {
17     return sp[i].f < sp[j].f
18 }
19 
20 func (sp sp_open) Swap(i, j int) {
21     sp[i], sp[j] = sp[j], sp[i]
22 }
23 
24 func (sp sp_open) exceptFirst() sp_open {
25     var newSps []*sp_item
26     for i := 1; i < len(sp); i++ {
27         newSps = append(newSps, sp[i])
28     }
29     return newSps
30 }
31 
32 func (sp sp_open) getIndex(x, y int) int {
33     for i, v := range sp {
34         if v.x == x && v.y == y {
35             return i
36         }
37     }
38     return -1
39 }

 這是open串列(帶檢索的串列)

Len()
Less(i, j int)
Swap(i, j int)
上面三個方法是自定義排序(
sp_item.f從小到大排序)
exceptFirst()
復制
sp_open 陣列并回傳, 不包含第一個 sp_item
getIndex(x, y int)
獲取與引數x,y匹配的 sp_item,回傳其當前索引或-1

 1 type sp_close []int
 2 
 3 func (sp sp_close) contains(x, y int) bool {
 4     for k := 0; k < len(sp); k += 2 {
 5         if sp[k] == x && sp[k+1] == y {
 6             return true
 7         }
 8     }
 9     return false
10 }

這是close串列(不在檢索的串列)

contains(x, y int)
sp_close 是否包含引數x,y

 1 type sp_dots [8]int
 2 
 3 func (sp sp_dots) getIndex(x, y int) int {
 4     for i := 0; i < 8; i += 2 {
 5         if sp[i] == x && sp[i+1] == y {
 6             return i
 7         }
 8     }
 9     return -1
10 }
11 
12 func (sp *sp_dots) put(x, y int) {
13     _x := x - 1
14     x_ := x + 1
15     _y := y - 1
16     y_ := y + 1
17     sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = x, _y, _x, y, x_, y, x, y_
18 }
19 
20 func (sp *sp_dots) putA(x, y int) {
21     _x := x - 1
22     x_ := x + 1
23     _y := y - 1
24     y_ := y + 1
25     sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = _x, _y, x_, _y, _x, y_, x_, y_
26 }

此型別用于獲取引數x,y周圍的4個點

put(x, y int)
填充 sp_dots, 周圍正對面的四個索引點
putA(x, y int)
填充 sp_dots, 周圍四個角的索引點

  1 type SeekPath struct {
  2     BevelAngle bool                //是否可以走斜角
  3     Timeout    time.Duration       //超時
  4     Junction   func(x, y int) bool //過濾
  5 }
  6 
  7 // x,y: 開始索引點; x1,y1: 結束索引點
  8 func (sp SeekPath) GetPath(x, y, x1, y1 int) []int {
  9     sTime := time.Now()
 10     eTime := time.Now().Add(sp.Timeout)
 11 
 12     var close sp_close             //不在檢測的串列
 13     var dots, dotsA, dotsB sp_dots //周圍的點
 14     var isSort bool                //如果為 true 則表示 open 串列已改變
 15 
 16     node := &sp_item{
 17         x: x, y: y,
 18         h: absInt(x1-x)*10 + absInt(y1-y)*10,
 19     }
 20     open := sp_open{node}
 21     node.f = node.h
 22     nd := node
 23 
 24     for {
 25         if len(open) == 0 || sTime.After(eTime) {
 26             break
 27         }
 28 
 29         //sp_item.f 從小到大排序
 30         if isSort {
 31             isSort = false
 32             sort.Sort(open)
 33         }
 34 
 35         //node 如果是目標就結束
 36         node = open[0]
 37         if node.x == x1 && node.y == y1 {
 38             nd = node
 39             break
 40         }
 41 
 42         if nd.h > node.h {
 43             nd = node
 44         }
 45 
 46         open = open.exceptFirst()             //從 open 串列洗掉第一個
 47         close = append(close, node.x, node.y) //把 node 加入 close 串列
 48 
 49         var state [4]bool //記錄四個面是否合法
 50         var dx, dy int
 51 
 52         //四個面
 53         dots.put(node.x, node.y)
 54         for i := 0; i < 8; i += 2 {
 55             dx, dy = dots[i], dots[i+1]
 56 
 57             //在close串列
 58             if close.contains(dx, dy) {
 59                 continue
 60             }
 61 
 62             //已在open串列
 63             g := open.getIndex(dx, dy)
 64             if g != -1 {
 65                 dot := open[g]
 66                 g = node.g + 10
 67                 if g < dot.g {
 68                     dot.g = g
 69                     dot.f = g + dot.h
 70                     dot.p = node
 71                     isSort = true
 72                 }
 73                 state[i/2] = true
 74                 continue
 75             }
 76 
 77             //索引點是否合法
 78             if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
 79                 close = append(close, node.x, node.y)
 80                 continue
 81             }
 82 
 83             g = node.g + 10
 84             h := absInt(x1-dx)*10 + absInt(y1-dy)*10
 85             open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
 86             isSort = true
 87             state[i/2] = true
 88         }
 89 
 90         //四個角
 91         dotsA.putA(node.x, node.y)
 92         for i := 0; i < 8; i += 2 {
 93             dx, dy = dotsA[i], dotsA[i+1]
 94 
 95             //在close串列
 96             if close.contains(dx, dy) {
 97                 continue
 98             }
 99 
100             //已在open串列
101             g := open.getIndex(dx, dy)
102             if g != -1 {
103                 dot := open[g]
104                 g = node.g + 14
105                 if g < dot.g {
106                     dot.g = g
107                     dot.f = g + dot.h
108                     dot.p = node
109                     isSort = true
110                 }
111                 continue
112             }
113 
114             //索引點是否合法
115             if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
116                 close = append(close, node.x, node.y)
117                 continue
118             }
119 
120             is := true
121             dotsB.put(dx, dy)
122             for i := 0; i < 8; i += 2 {
123                 g = dots.getIndex(dotsB[i], dotsB[i+1])
124                 if g == -1 {
125                     continue
126                 }
127                 if !state[g/2] {
128                     is = false
129                     break
130                 }
131             }
132             if is {
133                 g = node.g + 14
134                 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
135                 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
136                 isSort = true
137             }
138         }
139     }
140 
141     var path []int
142     for nd != nil {
143         path = append(path, nd.x, nd.y)
144         nd = nd.p
145     }
146 
147     return path
148 }

外部可實體  SeekPath 來獲取尋路后的路徑

 

使用示例:

 1 // 此結構是用于創建 SeekPath 的引數, 由客戶端定義
 2 type hh_SeekPath struct {
 3     BevelAngle bool   `json:"bevelAngle"`
 4     Disables   []bool `json:"disables"`
 5     LenX       int    `json:"lenX"`
 6     LenY       int    `json:"lenY"`
 7     X          int    `json:"x"`
 8     Y          int    `json:"y"`
 9     X1         int    `json:"x1"`
10     Y1         int    `json:"y1"`
11 }
12 
13 func main() {
14     //設定可同時執行的最大CPU數
15     runtime.GOMAXPROCS(runtime.NumCPU())
16     http.Handle("/", http.FileServer(http.Dir("./")))
17 
18     http.HandleFunc("/hh", func(w http.ResponseWriter, r *http.Request) {
19         w.Header().Set("Access-Control-Allow-Origin", "*") //*允許所有的域頭
20 
21         value := r.FormValue("value")
22         param := hh_SeekPath{}
23         err := json.Unmarshal([]byte(value), &param)
24         if err != nil {
25             fmt.Println("hh error: ", err)
26             return
27         }
28 
29         length := len(param.Disables)
30         lenMax := param.LenX * param.LenY
31         sp := SeekPath{
32             BevelAngle: param.BevelAngle,
33             Timeout:    time.Second * 10,
34 
35             //此回呼如果回傳false就把x,y添加到不在檢索串列(close)
36             Junction: func(x, y int) bool {
37                 //如果x,y超出最大邊界就回傳false
38                 if x >= param.LenX || y >= param.LenY {
39                     return false
40                 }
41                 //Disables[bool] 由客戶端隨機生成的障礙
42                 if length == lenMax {
43                     return param.Disables[x*param.LenY+y]
44                 }
45                 return true
46             },
47         }
48 
49         result, _ := json.Marshal(sp.GetPath(param.X, param.Y, param.X1, param.Y1))
50         fmt.Fprint(w, *(*string)(unsafe.Pointer(&result)))
51     })
52 
53     fmt.Println("瀏覽器地址: http://localhost:8080")
54     log.Fatal(http.ListenAndServe(":8080", nil))
55 }

 

下面是客戶端代碼(HTML)

 1 <!DOCTYPE html>
 2 <html lang = "zh-CN">
 3     
 4     <head>
 5         <meta charset = "utf-8" />
 6         <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"> <!-- 不允許用戶縮放 -->
 7         <style>
 8             *{margin:0;padding:0}
 9             body{overflow: hidden;}
10             .title{position: absolute;font-size: 12px; color: #000000; background-color: #ffffff;}
11         </style>
12     </head>
13 
14     <body>
15 
16         <p class="title">go A*尋路測驗: 點擊第一次為起點, 第二次點擊為終點</p>
17 
18         <script src = "./js/main.js" type = "module"></script>
19         
20     </body>
21 
22 </html>
index.html
 1 import { CanvasEvent, CanvasImageCustom, CanvasImageDraw, CanvasImageScroll, CanvasImage } from "./lib/ElementUtils.js"
 2 import { Ajax, UTILS } from "./lib/Utils.js";
 3 
 4 function main(){
 5     const size = 50;
 6     const imgA = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#eeeeee").stroke("#cccccc");
 7     const imgB = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#333333").stroke("#000000");
 8     const imgS = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#00ff00");
 9     const imgE = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#ff0000");
10     const imgP = new CanvasImageCustom().size(size, size).rect(size/2, 1).fill("#0000ff");
11     const cid = new CanvasImageDraw({width: innerWidth, height: innerHeight});
12     const cis = new CanvasImageScroll(cid, {scrollVisible: "auto"});
13     const cie = new CanvasEvent(cid);
14 
15     //發送給服務器的尋路引數
16     const param = {
17         bevelAngle: true, //是否可走斜角
18         disables: [], //禁用點
19         lenX: Math.floor(innerWidth/size), //索引x軸長度
20         lenY: 100, //索引y軸長度
21         x:0, y:0, //起點
22         x1: 0, y1: 0, //終點
23     }
24     var isEnd = true;
25     const pathsCI = []
26     const ajax = new Ajax({
27         url: "http://localhost:8080/hh",
28         success: v => {
29             v = JSON.parse(v);
30             for(let i = 0; i < v.length; i+=2){
31                 const ci = new CanvasImage(imgP).pos(v[i]*size, v[i+1]*size);
32                 pathsCI.push(ci);
33                 cid.list.push(ci);
34             }
35             cid.redraw();
36             isEnd = true;
37         },
38     });
39 
40     //點擊的回呼方法
41     var isSend = false;
42     function onclick(event){
43         if(isEnd === false) return alert("等待上一次的結果");
44         const ci = event.target;
45         if(isSend === false){
46             isSend = true;
47             param.x = Math.floor(ci.x / size);
48             param.y = Math.floor(ci.y / size);
49             imgS.pos(ci);
50             const c = pathsCI.length;
51             if(c !== 0){
52                 cid.list.splice(cid.list.indexOf(pathsCI[0]), c);
53                 pathsCI.length = 0;
54             }
55         } else {
56             isEnd = isSend = false;
57             param.x1 = Math.floor(ci.x / size);
58             param.y1 = Math.floor(ci.y / size);
59             ajax.send(`name=hh_SeekPath&value=https://www.cnblogs.com/weihexinCode/archive/2023/02/26/${JSON.stringify(param)}`);
60             imgE.pos(ci);
61         }
62         cid.redraw();
63     }
64 
65     //創建視圖和障礙點
66     for(let x = 0, i = 0; x < param.lenX; x++){
67         for(let y = 0, ci; y < param.lenY; y++, i++){
68             if(UTILS.random(0, 1) < 0.3){
69                 param.disables[i] = false;
70                 ci = cid.list[i] = new CanvasImage(imgB).pos(x * size, y * size);
71             } else {
72                 param.disables[i] = true;
73                 ci = cid.list[i] = new CanvasImage(imgA).pos(x * size, y * size);
74                 ci.addEventListener("click", onclick);
75             }
76         }
77     }
78     
79     //end
80     cis.bindScrolls();
81     cid.list.push(imgS, imgE);
82     cid.render();
83 }
84 
85 main();

 

結果圖:

 

 

原始碼下載地址: https://www.123pan.com/s/ylTuVv-nwhpH.html

 

修復了一個已知BUG:
  1 func (sp SeekPath) GetPath(x, y, x1, y1 int) []int {
  2     sTime := time.Now()
  3     eTime := time.Now().Add(sp.Timeout)
  4 
  5     var close sp_close             //不在檢測的串列
  6     var dots, dotsA, dotsB sp_dots //周圍的點
  7     var isSort bool                //如果為 true 則表示 open 串列已改變
  8 
  9     node := &sp_item{
 10         x: x, y: y,
 11         h: absInt(x1-x)*10 + absInt(y1-y)*10,
 12     }
 13     open := sp_open{node}
 14     node.f = node.h
 15     nd := node
 16 
 17     for {
 18         if len(open) == 0 || sTime.After(eTime) {
 19             break
 20         }
 21 
 22         //sp_item.f 從小到大排序
 23         if isSort {
 24             isSort = false
 25             sort.Sort(open)
 26         }
 27 
 28         //node 如果是目標就結束
 29         node = open[0]
 30         if node.x == x1 && node.y == y1 {
 31             nd = node
 32             break
 33         }
 34 
 35         if nd.h > node.h {
 36             nd = node
 37         }
 38 
 39         open = open.exceptFirst()             //從 open 串列洗掉第一個
 40         close = append(close, node.x, node.y) //把 node 加入 close 串列
 41 
 42         var state [4]bool //記錄四個面是否合法
 43         var dx, dy int
 44 
 45         //四個面
 46         dots.put(node.x, node.y)
 47         for i := 0; i < 8; i += 2 {
 48             dx, dy = dots[i], dots[i+1]
 49 
 50             //在close串列
 51             if close.contains(dx, dy) {
 52                 continue
 53             }
 54 
 55             //索引點是否合法
 56             if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
 57                 close = append(close, dx, dy)
 58                 continue
 59             }
 60 
 61             //已在open串列
 62             g := open.getIndex(dx, dy)
 63             if g != -1 {
 64                 dot := open[g]
 65                 g = node.g + 10
 66                 if g < dot.g {
 67                     dot.g = g
 68                     dot.f = g + dot.h
 69                     dot.p = node
 70                     isSort = true
 71                 }
 72                 state[i/2] = true
 73                 continue
 74             }
 75 
 76             g = node.g + 10
 77             h := absInt(x1-dx)*10 + absInt(y1-dy)*10
 78             open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
 79             isSort = true
 80             state[i/2] = true
 81         }
 82 
 83         //四個角
 84         dotsA.putA(node.x, node.y)
 85         for i := 0; i < 8; i += 2 {
 86             dx, dy = dotsA[i], dotsA[i+1]
 87 
 88             //在close串列
 89             if close.contains(dx, dy) {
 90                 continue
 91             }
 92 
 93             //索引點是否合法
 94             if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
 95                 close = append(close, dx, dy)
 96                 continue
 97             }
 98 
 99             is := true
100             g := 0
101             dotsB.put(dx, dy)
102             for i := 0; i < 8; i += 2 {
103                 g = dots.getIndex(dotsB[i], dotsB[i+1])
104                 if g == -1 {
105                     continue
106                 }
107                 if !state[g/2] {
108                     is = false
109                     break
110                 }
111             }
112 
113             if !is {
114                 continue
115             }
116 
117             //已在open串列
118             g = open.getIndex(dx, dy)
119             if g != -1 {
120                 dot := open[g]
121                 g = node.g + 14
122                 if g < dot.g {
123                     dot.g = g
124                     dot.f = g + dot.h
125                     dot.p = node
126                     isSort = true
127                 }
128                 continue
129             }
130 
131             g = node.g + 14
132             h := absInt(x1-dx)*10 + absInt(y1-dy)*10
133             open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
134             isSort = true
135         }
136     }
137 
138     var path []int
139     for nd != nil {
140         path = append(path, nd.x, nd.y)
141         nd = nd.p
142     }
143 
144     return path
145 }
SeekPath.GetPath方法

注意: https://www.123pan.com/s/ylTuVv-nwhpH.html共享的原始碼需要手動更換 SeekPath 下的 GetPath 方法才能解決這個BUG




轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/545107.html

標籤:其他

上一篇:Java刷題常用的資料結構總結

下一篇:Java流程控制:用戶互動Scanner、選擇結構

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more