当前位置: 首页 > news >正文

Go+快速开始详细指南

Go+快速开始

Go+编程语言是为工程、STEM教育和数据科学设计的。

  • 对于工程:用儿童能掌握的最简单的语言工作。
  • 对于STEM教育:学习一门可以在未来工作中使用的工程语言。
  • 对于数据科学:用同一种语言与工程师交流。

安装方法

现在,我们建议您从源代码安装Go+。

注意:需要go1.18或更高版本

git clone https://github.com/goplus/gop.git
cd gop# On mac/linux run:
./all.bash
# On Windows run:
all.bat

实际上,all.bashall.bat 将会在底层用 go run cmd/make.go.

在Go+ playground里运行

如果你不想安装Go+,你可以在Go+ playground中编写Go+程序。这是体验Go+的最快方式。

  • Go+ playground based on Docker: https://play.goplus.org/
  • Go+ playground based on GopherJS: https://jsplay.goplus.org/

你可以和你的朋友分享你的Go+代码。这是我的“Hello world”程序:

  • https://play.goplus.org/p/AAh_gQAKAZR.

你好,世界

println "Hello world"

将这段代码保存到一个名为“hello.gop”的文件中。现在执行:’ gop run hello.gop '。

恭喜你——你刚刚编写并执行了你的第一个Go+程序!

你可以用gop build hello.gop编译一个不需要执行的程序。

有关所有支持的命令,请参阅’ gop help '。

println是为数不多的内置函数之一。它将传递给它的值打印到标准输出。

详见https://tutorial.goplus.org/hello-world。

运行包含多个文件的项目文件夹

假设您有一个包含几个.gop文件的文件夹,并且您想要将它们全部编译成一个程序。只要做:gop run .

传递参数也可以,所以你可以这样做:

gop run . --yourparams some_other_stuff.

然后你的程序可以像这样使用CLI参数:

import "os"println os.Args

注释

# This is a single line comment.// This is a single line comment./*
This is a multiline comment.
*/

变量

name := "Bob"
age := 20
largeNumber := int128(1 << 65)
println name, age
println largeNumber

变量用:= 声明和初始化。

变量的类型是从右边的值推断出来的。

要选择不同的类型,请使用类型转换:

表达式’ T(v) ‘将值’ v '转换为“T”型。

初始化vs赋值

请注意’:= ‘和’ = '之间的(重要)区别。

':= ‘用于声明和初始化,’ = '用于赋值。

age = 21

这段代码无法编译,因为没有声明变量“age”。所有变量都需要在Go+中声明。

age := 21

可以在一行中修改多个变量的值。

通过这种方式,可以在没有中间变量的情况下交换它们的值。

a, b := 0, 1
a, b = b, a
println a, b // 1, 0

Go+类型

基本数据类型

boolint8    int16   int32   int    int64    int128
uint8   uint16  uint32  uint   uint64   uint128uintptr // similar to C's size_tbyte // alias for uint8
rune // alias for int32, represents a Unicode code pointstringfloat32 float64complex64 complex128bigint bigratunsafe.Pointer // similar to C's void*any // alias for Go's interface{}

字符串

name := "Bob"
println name.len  // 3
println name[0]   // 66
println name[1:3] // ob
println name[:2]  // Bo
println name[2:]  // b// or using octal escape `\###` notation where `#` is an octal digit
println "\141a"   // aa// Unicode can be specified directly as `\u####` where # is a hex digit
// and will be converted internally to its UTF-8 representation
println "\u2605"  // ★

字符串值是不可变的。你不能改变元素:

s := "hello 🌎"
s[0] = `H` // not allowed

请注意,对字符串进行索引将生成一个’ byte ‘,而不是’ rune ‘或另一个’ string '。

字符串可以很容易地转换为整数:

s := "12"
a, err := s.int
if err != nil {println(err)return
}
println("a:", a)b := s.int! // will panic if s isn't a valid integer
println("b:", b)
字符串操作符
name := "Bob"
bobby := name + "by" // + is used to concatenate strings
println bobby // Bobbys := "Hello "
s += "world"
println s // Hello world

Go+中的所有操作符两边必须具有相同类型的值。不能连接一个整型转换为字符串:

age := 10
println "age = " + age // not allowed

我们也可以将’ age ‘转换为’ string ':

age := 10
println "age = " + age.string

Runes

’ rune’表示单个Unicode字符,是’ int32 '的别名。

rocket := '🚀'
println rocket         // 128640
println string(rocket) // 🚀

Numbers

a := 123

这将把123的值赋给’ a ‘。默认情况下’ a ‘的类型为’ int '。

您还可以使用十六进制,二进制或八进制表示法来表示整数字面值:

a := 0x7B
b := 0b01111011
c := 0o173

所有这些都会被赋相同的值123。它们都有类型’ int ',不管你用什么符号。

Go+还支持用’ _ '作为分隔符书写数字:

num := 1_000_000 // same as 1000000

如果你想要一个不同类型的整数,你可以使用强制转换:

a := int64(123)
b := uint8(12)
c := int128(12345)

赋值浮点数的工作方式相同:

f1 := 1.0
f2 := float32(3.14)

如果不显式指定类型,默认情况下float字面值将具有’ float64 '类型。

Float字面值也可以声明为10的幂:

f0 := 42e1   // 420
f1 := 123e-2 // 1.23
f2 := 456e+2 // 45600

Go+内置了对有理数的支持:

a := 1r << 200  // suffix `r` means `rational`
b := bigint(1 << 200)

你可以将bool类型转换为数字类型(这在Go中不支持):

println int(true)       // 1
println float64(true)   // 1
println complex64(true) // (1+0i)

切片

切片是具有相同类型的数据元素的集合。切片字面量是用方括号括起来的表达式列表。单个元素可以是使用index表达式访问。索引从“0”开始:

nums := [1, 2, 3]
println nums      // [1 2 3]
println nums.len  // 3
println nums[0]   // 1
println nums[1:3] // [2 3]
println nums[:2]  // [1 2]
println nums[2:]  // [3]nums[1] = 5
println nums // [1 5 3]

自动推断切片文字的类型。

a := [1, 2, 3]   // []int
b := [1, 2, 3.4] // []float64
c := ["Hi"]      // []string
d := ["Hi", 10]  // []any
d := []          // []any

强制转换切片片字面量也有效。

a := []float64([1, 2, 3]) // []float64

集合

a := {"Hello": 1, "xsw": 3}     // map[string]int
b := {"Hello": 1, "xsw": 3.4}   // map[string]float64
c := {"Hello": 1, "xsw": "Go+"} // map[string]any
d := {}                         // map[string]any

如果没有找到键,默认返回零值:

a := {"Hello": 1, "xsw": 3}
c := {"Hello": 1, "xsw": "Go+"}
println a["bad_key"] // 0
println c["bad_key"] // <nil>

您还可以检查是否存在一个键,并获取它的值。

a := {"Hello": 1, "xsw": 3}
if v, ok := a["xsw"]; ok {println "its value is", v
}

模块导入

模块可以使用’ import '关键字导入:

import "strings"x := strings.NewReplacer("?", "!").Replace("Hello, world???")
println x // Hello, world!!!

模块导入别名

任何导入的模块名都可以使用别名:

import strop "strings"x := strop.NewReplacer("?", "!").Replace("Hello, world???")
println x // Hello, world!!!

表达式和语句

If…else

在Go+中,’ if '语句非常简单,与大多数其他语言类似。

与其他类c语言不同,在条件周围没有括号,并且总是需要大括号。

a := 10
b := 20
if a < b {println "a < b"
} else if a > b {println "a > b"
} else {println "a == b"
}

For循环

Go+只有一个循环关键字:’ for ',有几种形式。

for/<-

这是最常见的形式。您可以将它与切片、映射、数字范围或自定义迭代器一起使用。

Slice for

’ for value < - arr '形式用于遍历切片的元素。

numbers := [1, 3, 5, 7, 11, 13, 17]
sum := 0
for x <- numbers {sum += x
}
println sum // 57

如果需要索引,可以使用另一种形式’ for index, value < - arr ’

names := ["Sam", "Peter"]
for i, name <- names {println i, name// 0 Sam// 1 Peter
}
Map for
m := {"one": 1, "two": 2}
for key, val <- m {println key, val// one 1// two 2
}
for key, _ <- m {println key// one// two
}
for val <- m {println val// 1// 2
}
Range for

你可以在for循环中使用range expression (start:end:step)。

for i <- :5 {println i// 0// 1// 2// 3// 4
}
for i <- 1:5 {println i// 1// 2// 3// 4
}
for i <- 1:5:2 {println i// 1// 3
}
for/<-/if

所有for/<-形式的循环都可以有一个可选的’ if '条件。

numbers := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for num <- numbers if num%3 == 0 {println num// 0// 3// 6// 9
}for num <- :10 if num%3 == 0 {println num// 0// 3// 6// 9
}
Condition for
sum := 0
i := 1
for i <= 100 {sum += ii++
}
println sum // 5050

这种形式的循环类似于其他语言中的“while”循环。

一旦布尔条件求值为false,循环将停止迭代。

同样,条件周围没有括号,并且总是需要大括号。

C for
for i := 0; i < 10; i += 2 {// Don't print 6if i == 6 {continue}println i// 0// 2// 4// 8
}

最后,还有传统C风格的for循环。它比“while”形式更安全

因为使用后者很容易忘记更新计数器和get

陷入无限循环。

Bare for
for {// ...
}

可以省略该条件,从而导致无限循环。你可以使用’ break ‘或’ return '来结束循环。

错误处理

我们在Go+中重新定义了错误处理规范。我们称它们为“ErrWrap表达式”:

expr! // panic if err
expr? // return if err
expr?:defval // use defval if err

如何使用它们?下面是一个例子:

import ("strconv"
)func add(x, y string) (int, error) {return strconv.Atoi(x)? + strconv.Atoi(y)?, nil
}func addSafe(x, y string) int {return strconv.Atoi(x)?:0 + strconv.Atoi(y)?:0
}println `add("100", "23"):`, add("100", "23")!sum, err := add("10", "abc")
println `add("10", "abc"):`, sum, errprintln `addSafe("10", "abc"):`, addSafe("10", "abc")

The output of this example is:

add("100", "23"): 123
add("10", "abc"): 0 strconv.Atoi: parsing "abc": invalid syntax===> errors stack:
main.add("10", "abc")/Users/xsw/tutorial/15-ErrWrap/err_wrap.gop:6 strconv.Atoi(y)?addSafe("10", "abc"): 10

与相应的Go代码相比,它更清晰,更具可读性。

最有趣的是,返回错误包含了整个错误堆栈。当我们遇到错误时,很容易找到根本原因。

这些“ErrWrap表达式”是如何工作的?有关详细信息,请参阅错误处理

函数

func add(x int, y int) int {return x + y
}println add(2, 3) // 5

返回多个值

func foo() (int, int) {return 2, 3
}a, b := foo()
println a // 2
println b // 3
c, _ := foo() // ignore values using `_`

可变参数

func sum(a ...int) int {total := 0for x <- a {total += x}return total
}println sum(2, 3, 5) // 10

输出参数可以有名称。

func sum(a ...int) (total int) {for x <- a {total += x}return // don't need return values if they are assigned
}println sum(2, 3, 5) // 10

高阶函数

函数也可以是参数。

func square(x float64) float64 {return x*x
}func abs(x float64) float64 {if x < 0 {return -x}return x
}func transform(a []float64, f func(float64) float64) []float64 {return [f(x) for x <- a]
}y := transform([1, 2, 3], square)
println y // [1 4 9]z := transform([-3, 1, -5], abs)
println z // [3 1 5]

Lambda表达式

你也可以使用’ lambda表达式’来定义一个匿名函数。

func transform(a []float64, f func(float64) float64) []float64 {return [f(x) for x <- a]
}y := transform([1, 2, 3], x => x*x)
println y // [1 4 9]z := transform([-3, 1, -5], x => {if x < 0 {return -x}return x
})
println z // [3 1 5]

结构体

自定义的迭代器

For range of UDT
type Foo struct {
}// Gop_Enum(proc func(val ValType)) or:
// Gop_Enum(proc func(key KeyType, val ValType))
func (p *Foo) Gop_Enum(proc func(key int, val string)) {// ...
}foo := &Foo{}
for k, v := range foo {println k, v
}for k, v <- foo {println k, v
}println {v: k for k, v <- foo}

注意:你不能在udt.Gop_Enum(callback)的范围内使用break/continue或return语句

For range of UDT2
type FooIter struct {
}// (Iterator) Next() (val ValType, ok bool) or:
// (Iterator) Next() (key KeyType, val ValType, ok bool)
func (p *FooIter) Next() (key int, val string, ok bool) {// ...
}type Foo struct {
}// Gop_Enum() Iterator
func (p *Foo) Gop_Enum() *FooIter {// ...
}foo := &Foo{}
for k, v := range foo {println k, v
}for k, v <- foo {println k, v
}println {v: k for k, v <- foo}

推断结构类型

type Config struct {Dir   stringLevel int
}func foo(conf *Config) {// ...
}foo {Dir: "/foo/bar", Level: 1}

这里’ foo {Dir: “/foo/bar”, Level: 1} ‘等价于’ foo(&Config{Dir: “/foo/bar”, Level: 1}) ‘。然而,你不能将’ foo(&Config{“/foo/bar”, 1}) ‘替换为’ foo {“/foo/bar”, 1} ‘,因为将’ {“/foo/bar”, 1} '视为结构字面值会令人困惑。

您还可以在返回语句中省略结构类型。例如:

type Result struct {Text string
}func foo() *Result {return {Text: "Hi, Go+"} // return &Result{Text: "Hi, Go+"}
}

重载操作符

import "math/big"type MyBigInt struct {*big.Int
}func Int(v *big.Int) MyBigInt {return MyBigInt{v}
}func (a MyBigInt) + (b MyBigInt) MyBigInt { // binary operatorreturn MyBigInt{new(big.Int).Add(a.Int, b.Int)}
}func (a MyBigInt) += (b MyBigInt) {a.Int.Add(a.Int, b.Int)
}func -(a MyBigInt) MyBigInt { // unary operatorreturn MyBigInt{new(big.Int).Neg(a.Int)}
}a := Int(1r)
a += Int(2r)
println a + Int(3r)
println -a

自动属性

Let’s see an example written in Go+:

import "gop/ast/goptest"doc := goptest.New(`... Go+ code ...`)!println doc.Any().FuncDecl().Name()

在许多语言中,有一个名为" property “的概念,它有” get “和” set "方法。

假设我们有’ get property ',上面的例子将是:

import "gop/ast/goptest"doc := goptest.New(`... Go+ code ...`)!println doc.any.funcDecl.name

在Go+中,我们引入了一个名为“自动属性”的概念。它是一个“get属性”,但是是自动实现的。如果我们有一个名为’ Bar() ‘的方法,那么我们将同时有一个名为’ Bar ‘的’ get属性’。

Go/Go+ 混合程序设计

这是一个展示如何在同一个包中混合Go/Go+代码的示例。

在这个例子中,我们有一个名为’ a.go '的Go源文件:

package mainimport "fmt"func p(a interface{}) {sayMix()fmt.Println("Hello,", a)
}

我们有一个Go+源文件名为’ b.gop ':

func sayMix() {println "Mix Go and Go+"
}p "world"

你可以看到Go调用名为’ sayMix ‘的Go+函数,Go+调用名为’ p '的Go函数。正如你在Go编程中习惯的那样,这种循环引用是允许的。

运行’ gop Run . '来查看这个示例的输出:

Mix Go and Go+
Hello, world

在监视模式下运行Go+

’ gop '命令可以在监视模式下运行,以便每次更改Go+文件时将其转换为Go文件:

gop watch [-gentest] [dir]

默认情况下,’ gop watch ‘不会转换测试文件(通常以’ _test.gop ‘结尾)。你可以指定’ -gentest '标志来强制转换所有Go+文件。

从Go+调用C

  • ’ gop c ‘命令(相当于独立的’ c2go '命令)可用于将c项目转换为Go项目。
  • ’ import “C” ‘和’ import “C/xxx” '用于导入c2go转换的C项目。其中“import”C是“import”C/github.com/goplus/libc”的缩写。
  • ’ C"xxx" '语法表示C风格的字符串常量。

Here is an example to show how Go+ interacts with C.

import "C"C.printf C"Hello, c2go!\n"
C.fprintf C.stderr, C"Hi, %7.1f\n", 3.14

在这个例子中,我们调用两个C标准函数’ printf ‘和’ fprintf ‘,传递一个C变量’ stderr ‘和两个C字符串,形式为’ C"xxx" ’ (Go+语法表示C风格字符串)。

运行’ gop run . '来查看这个示例的输出:

Hello, c2go!
Hi,     3.1

当然,目前Go+对C语言的支持只是一个预览版本,还没有到实际工程中可用的程度。就libc而言,目前的移民进度只有5%左右,这只是一个开始。

在即将到来的Go+ v1.2版本计划中,完全支持C语言被列为首要任务。当然,对Go和Go模板的支持也在计划之中,这对Go/Go+混合项目来说是一个至关重要的功能增强。

数据处理

有理数

我们引入有理数作为原始Go+类型。我们使用后缀“r”来表示有理字面值。例如, 1r << 200 表示一个大int,它的值等于 2200.

a := 1r << 200
b := bigint(1 << 200)

默认情况下,’ 1r ‘的类型为’ bigint ’

4/5r表示有理常数4/5。

它的类型是’ bigrat '。

a := 4/5r
b := a - 1/3r + 3 * 1/2r
println a, b // 4/5 59/30

转换有理数的工作方式类似于其他基本数据类型:

列表推导式

a := [x*x for x <- [1, 3, 5, 7, 11]]
b := [x*x for x <- [1, 3, 5, 7, 11] if x > 3]
c := [i+v for i, v <- [1, 3, 5, 7, 11] if i%2 == 1]arr := [1, 2, 3, 4, 5, 6]
d := [[a, b] for a <- arr if a < b for b <- arr if b > 2]x := {x: i for i, x <- [1, 3, 5, 7, 11]}
y := {x: i for i, x <- [1, 3, 5, 7, 11] if i%2 == 1}
z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "Go+"} if k > 3}

从集合中选择数据

type student struct {name  stringscore int
}students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}]unknownScore, ok := {x.score for x <- students if x.name == "Unknown"}
jasonScore := {x.score for x <- students if x.name == "Jason"}println unknownScore, ok // 0 false
println jasonScore // 80

检查集合中是否存在数据

type student struct {name  stringscore int
}students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}]hasJason := {for x <- students if x.name == "Jason"} // is any student named Jason?
hasFailed := {for x <- students if x.score < 60}     // is any student failed?

Unix shebang

现在可以使用Go+程序作为shell脚本。例如:

#!/usr/bin/env -S gop runprintln "Hello, Go+"println 1r << 129
println 1/3r + 2/7r*2arr := [1, 3, 5, 7, 11, 13, 17, 19]
println arr
println [x*x for x <- arr, x > 3]m := {"Hi": 1, "Go+": 2}
println m
println {v: k for k, v <- m}
println [k for k, _ <- m]
println [v for v <- m]

与Go的兼容性

所有Go的特性都将被支持.

所有Go包(即使这些包使用’ cgo ')都可以通过Go+.导入

import ("fmt""strings"
)x := strings.NewReplacer("?", "!").Replace("hello, world???")
fmt.Println "x:", x

所有Go+包也可以导入到Go程序中。你需要做的就是使用’ gop ‘命令而不是’ go ’

首先,让我们创建一个名为“14-Using-goplus-in-Go”的目录。

然后在其中编写一个名为foo的Go+包:

package foofunc ReverseMap(m map[string]int) map[int]string {return {v: k for k, v <- m}
}

然后在Go包中使用它14-Using-goplus-in-Go/gomain

package mainimport ("fmt""github.com/goplus/tutorial/14-Using-goplus-in-Go/foo"
)func main() {rmap := foo.ReverseMap(map[string]int{"Hi": 1, "Hello": 2})fmt.Println(rmap)
}

如何构建这个示例?你可以用:

gop install -v ./...

字节码 vs Go代码

当我们使用’ gop '命令时,它会生成Go代码将Go+包转换为Go包。

gop run     # Run a Go+ program
gop install # Build Go+ files and install target to GOBIN
gop build   # Build Go+ files
gop test    # Test Go+ packages
gop fmt     # Format Go+ packages
gop clean   # Clean all Go+ auto generated files
gop go      # Convert Go+ packages into Go packages

当我们使用’ igop '命令时,它会生成字节码来执行。

igop  # Run a Go+ program

在字节码模式下,Go+不支持’ cgo ‘。然而,在Go代码生成模式下,Go+完全支持’ cgo '。

References:https://tutorial.goplus.org/

相关文章:

Go+快速开始详细指南

Go快速开始 Go编程语言是为工程、STEM教育和数据科学设计的。 对于工程:用儿童能掌握的最简单的语言工作。对于STEM教育:学习一门可以在未来工作中使用的工程语言。对于数据科学:用同一种语言与工程师交流。 安装方法 现在&#xff0c;我们建议您从源代码安装Go。 注意:需…...

SQL:一行中存在任一指标就显示出来

当想要统计的两个指标不在一张表中时&#xff0c;需要做关联。但很多情况下&#xff0c;也没有办法保证其中一张表的维度是全的&#xff0c;用left join或right join可能会导致数据丢失。所以借助full join处理。 1&#xff09;如&#xff0c;将下面的数据处理成表格中的效果&…...

【代码随想录06】454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

目录 454. 四数相加 II题目描述做题思路参考代码 383. 赎金信题目描述做题思路参考代码 15. 三数之和题目描述参考代码 18. 四数之和题目描述参考代码 454. 四数相加 II 题目描述 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你…...

NodeJs 第十五章 session

Session代表服务器和客户端一次会话的过程。 在计算机科学领域来说&#xff0c;尤其是在网络领域&#xff0c;会话(session)是一种持久网络协议&#xff0c;在用户(或用户代理)端和服务器端之间创建关联&#xff0c;从而起到交换数据包的作用机制&#xff0c;session在网络协议…...

JRTP实时音视频传输(1)-必做的环境搭建与demo测试

1.需求 1&#xff09;支持协议自动切换。在网络优的情况下使用TCP、网络差的情况下使用UDP&#xff0c;满足实时音视频传输需求&#xff0c; 2&#xff09;支持RTCP &#xff0c;流量控制&#xff0c;阻塞控制等。需要能支持RTCP&#xff0c;这样便能在这个基础上&#xff0c;…...

腿部臀部训练

坐式蹬腿器 100kg&#xff0c;是器械的极限了&#xff0c;也差不多是我的极限&#xff0c;深蹲是40kg&#xff0c;应该还可以加点&#xff0c;大腿外扩器55kg&#xff0c;没有尝试能不能做更重的&#xff0c;羡慕健身房里面的好身材的同学&#xff0c;自己得好好练 1.21健身房关…...

windows系统下docker软件中使用ubuntu发行版本的linux系统

1.软件下载 官网下载地址 下载安装之后&#xff0c;再去微软商店下载wsl软件&#xff0c;可以直接用&#xff0c;或者也可以使用命令行拉取&#xff08;下面会讲&#xff09; 2.在docker里面创建容器的两种方法 2.1.命令行创建 前言&#xff1a;输入 winr 打开命令行进行下面…...

vue实现小球掉落

首先&#xff0c;将小球儿动画代码封装成组件&#xff0c;创建个文件&#xff0c;例如qiu.js let createBall (left, top,box) > {// 点击事件 const {clientX,clienty} ev createBall(clientX,clienty)const ball document.createElement(div);ball.style.position a…...

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV&#xff0c;还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。 动态PV需要两个组件 存储卷插件&#xff1a;Provisioner(存储分配器)根据定义的属性创建PV StorageClass&#xff1a;定义属性 存储卷插件 存储卷插件&#xff1a;k8s本…...

go最佳实践:如何舒适地编码

什么是 "最佳 "做法&#xff1f; 有很多做法&#xff1a;你可以自己想出来&#xff0c;在互联网上找到&#xff0c;或者从其他语言中拿来&#xff0c;但由于其主观性&#xff0c;并不总是容易说哪一个比另一个好。”最佳”的含义因人而异&#xff0c;也取决于其背景…...

C# 消息队列、多线程、回滚、并行编程、异步编程、反射

消息队列 消息队列是一种在应用程序之间传递消息的异步通信机制。它可以使应用程序解耦并提高系统的可伸缩性和可靠性。在 C# 中&#xff0c;你可以使用多个消息队列技术&#xff0c;其中一种广泛使用的技术是 RabbitMQ。 RabbitMQ 是一个开源的消息代理&#xff0c;实现了高…...

汇编代码生成和编译器的后端

1.前置程序&#xff1a;语义分析和中间代码生成 基于SLR(1)分析的语义分析及中间代码生成程序-CSDN博客https://blog.csdn.net/lijj0304/article/details/135097554?spm1001.2014.3001.5501 2.程序目标 在前面编译器前端实现的基础上&#xff0c;将所生成的中间代码翻译成某…...

MySQL 8.0中新增的功能(九)

FROM_UNIXTIME()、UNIX_TIMESTAMP()和CONVERT_TZ()的64位支持 根据MySQL 8.0.28版本的更新&#xff0c;FROM_UNIXTIME()、UNIX_TIMESTAMP() 和 CONVERT_TZ() 函数现在在支持64位的平台上处理64位值。这包括64位版本的Linux、MacOS和Windows。在兼容的平台上&#xff0c;UNIX_T…...

QT基础篇(8)QT5模型视图结构

1.概述 QT5的模型视图结构主要包括模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和委托&#xff08;Delegate&#xff09;三个部分。 模型&#xff08;Model&#xff09;&#xff1a;模型是数据的抽象表示&#xff0c;负责存储和管理数据。它可以是自…...

vue3-响应式基础之reactive

reactive() 还有另一种声明响应式状态的方式&#xff0c;即使用 reactive() API。与将内部值包装在特殊对象中的 ref 不同&#xff0c;reactive() 将使对象本身具有响应性&#xff1a; 「点击按钮1」 <script lang"ts" setup> import { reactive } from vuec…...

【ceph】如何将osd的内容挂载出来---ceph-objectstore-tool 实现

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

怎样实现安全便捷的网间数据安全交换?

数据安全交换是指在数据传输过程中采取一系列措施来保护数据的完整性、机密性和可用性。网间数据安全交换&#xff0c;则是需要进行跨网络、跨网段甚至跨组织地进行数据交互&#xff0c;对于数据的传输要求会更高。 大部分企业都是通过网闸、DMZ区、VLAN、双网云桌面等方式实现…...

微信小程序定义并获取日志/实时log信息

步骤一&#xff1a;开通实时日志 可以在开发者工具->详情->性能质量->实时日志&#xff0c;点击前往&#xff0c;在浏览器打开we分析界面&#xff1a; 也可登录小程序管理后台&#xff0c;点击统计进入we分析&#xff1a; 在we分析界面找到性能质量&#xff0c;打开实…...

海外代理IP怎么用?常见使用问题及解决方案

海外代理IP是指提供全球范围内的代理服务器&#xff0c;代理服务器充当IP与目标网站之间的中介&#xff0c;可以起到安全匿名、提高网速、突破网络壁垒的作用。在使用代理IP的过程中&#xff0c;用户可能会遇到各种挑战&#xff0c;如连接问题、速度慢等。理解这些问题的原因并…...

DP:数位DP

数位DP的大致思想&#xff1a;枚举每一位能选取的合法值。 1. LC 2376 统计特殊整数 说是DP&#xff0c;但实际上状态转移方程挺难写的&#xff0c;毕竟是枚举集合论&#xff0c;这里就不贴状态转移方程了。总体的写法其实是搜索记忆化。之所以称之为DP&#xff0c;是因为&am…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...