go学习笔记接口部分

article/2025/9/11 1:13:11

Go学习笔记

      • 接口
        • 接口定义方法
          • 练习 11.1 simple_interface.go:
          • 练习 11.2 interfaces_poly2.go:
        • 接口嵌套接口
        • 如何判断接口类型
          • 方法一varI.(T)
          • 方法二type-switch
            • 练习 11.4 simple_interface2.go:
        • 测试一个值是否实现了某个接口
        • 接口方法设计的注意事项和规范
            • 练习 11.5 interfaces_ext.go:
            • 练习 11.6 point_interfaces.go:
            • 练习 11.7 float_sort.go / float_sortmain.go:
            • 练习 11.8 sort.go / sort_persons.go:
        • 空接口
            • 练习 11.9 simple_interface3.go:
          • 用空接口构建通用类型或包含不同类型变量的数组
            • 练习 11.10 min_interface.go / minmain.go:
        • 反射
          • 通过反射修改(设置)值
          • 反射结构
            • 练习 11.11:map_function_interface.go:
            • 练习 11.12:map_function_interface_var.go:
            • 练习 11.13:main_stack.go—stack/stack_general.go:

接口

接口定义方法

接口定义了一组方法(方法集),但是这些方法不包含(实现)代码:它们没有被实现(它们是抽象的)。接口里也不能包含变量。
例子:

type Namer interface {Method1(param_list) return_typeMethod2(param_list) return_type...
}
练习 11.1 simple_interface.go:

定义一个接口 Simpler,它有一个 Get() 方法和一个 Set(),Get() 返回一个整型值,Set() 有一个整型参数。创建一个结构体类型 Simple 实现这个接口。

接着定一个函数,它有一个 Simpler 类型的参数,调用参数的 Get() 和 Set() 方法。在 main 函数里调用这个函数,看看它是否可以正确运行。

package mainimport ("fmt"
)type Simpler interface {get() intset(i int) Simpler
}func show(a Simpler) {fmt.Print(a.get(), "\n")a = a.set(10)fmt.Print(a.get(), "\n")}type ss struct {i int
}func (s ss) get() int {return s.i
}
func (s ss) set(i int) Simpler {s.i = ireturn s
}
func main() {var si Simplersi = ss{1}show(si)
}
练习 11.2 interfaces_poly2.go:

a) 扩展 interfaces_poly.go 中的例子,添加一个 Circle 类型

b) 使用一个抽象类型 Shape(没有字段) 实现同样的功能,它实现接口 Shaper,然后在其他类型里内嵌此类型。扩展 10.6.5 中的例子来说明覆写。

package mainimport "fmt"type shaper interface {say(string2 string)
}
type shape struct {
}func (a *shape) say(string2 string) {fmt.Print("i am ", string2)
}type circle struct {name stringshape
}func main() {c := circle{"circle", shape{}}c.say(c.name)
}

在这里插入图片描述

接口嵌套接口

一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样。

比如接口 File 包含了 ReadWrite 和 Lock 的所有方法,它还额外有一个 Close() 方法。

type ReadWrite interface {Read(b Buffer) boolWrite(b Buffer) bool
}type Lock interface {Lock()Unlock()
}type File interface {ReadWriteLockClose()
}

如何判断接口类型

方法一varI.(T)

一个接口类型的变量 varI 中可以包含任何类型的值,必须有一种方式来检测它的 动态 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 类型断言 来测试在某个时刻 varI 是否包含类型 T 的值:

v := varI.(T)      

可以多使用下面的代码进行判断,如果转换合法,v 是 varI 转换到类型 T 的值,ok 会是 true;否则 v 是类型 T 的零值,ok 是 false,也没有运行时错误发生。

if v, ok := varI.(T); ok {  // checked type assertionProcess(v)return
}
方法二type-switch

接口变量的类型也可以使用一种特殊形式的 switch 来检测:type-switch
例子:

switch t := areaIntf.(type) {
case *Square:fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:fmt.Printf("nil value: nothing to check?\n")
default:fmt.Printf("Unexpected type %T\n", t)
}
练习 11.4 simple_interface2.go:

接着练习 11.1 中的内容,创建第二个类型 RSimple,它也实现了接口 Simpler,写一个函数 fi(),使它可以区分 Simple 和 RSimple 类型的变量。

package mainimport ("fmt"
)type Simpler interface {get() intset(i int)
}
type Rsimple struct {i int
}func (s Rsimple) get() int {return s.i
}
func (s Rsimple) set(i int) {s.i = i
}type Simple struct {i int
}func (s Simple) get() int {return s.i
}
func (s Simple) set(i int) {s.i = i
}
func panduan(items interface{}) {switch items.(type) {case Simple:fmt.Print("it is Simple \n")case Rsimple:fmt.Print("it is Rsimple\n")default:fmt.Print("nothing\n")}
}
func main() {var ss Simplers := Simple{1}s1 := Rsimple{2}ss = spanduan(ss)ss = s1panduan(ss)}

在这里插入图片描述

测试一个值是否实现了某个接口

假定 v 是一个值,然后我们想测试它是否实现了 Stringer 接口,可以这样做:

func main() {var ss Simplers := Simple{1}s1 := Rsimple{2}ss = spanduan(ss)ss = s1panduan(ss)if sv, ok := interface{}(s1).(Simpler); ok {fmt.Printf("v implements Get(): %d\n", sv.get())}
}

如果v得类型不是接口那么我们需要使用interface{}先将他转换为接口

接口方法设计的注意事项和规范

在接口上调用方法时,必须有和方法定义时相同的接收者类型或者是可以根据具体类型 P 直接辨识的:

指针方法可以通过指针调用
值方法可以通过值调用
接收者是值的方法可以通过指针调用,因为指针会首先被解引用
接收者是指针的方法不可以通过值调用,因为存储在接口中的值没有地址
将一个值赋值给一个接口时,编译器会确保所有可能的接口方法都可以在此值上被调用,因此不正确的赋值在编译期就会失败。

译注

Go 语言规范定义了接口方法集的调用规则:

类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
类型 T 的可调用方法集包含接受者为 T 的所有方法
类型 T 的可调用方法集不包含接受者为 *T 的方法
上述例子改成指针调用的例子:

package mainimport ("fmt"
)type Simpler interface {get() intset(i int)
}
type Rsimple struct {i int
}func (s *Rsimple) get() int {return s.i
}
func (s *Rsimple) set(i int) {s.i = i
}type Simple struct {i int
}func (s *Simple) get() int {return s.i
}
func (s *Simple) set(i int) {s.i = i
}
func panduan(items interface{}) {switch items.(type) {case *Simple:fmt.Print("it is Simple \n")case *Rsimple:fmt.Print("it is Rsimple\n")default:fmt.Print("nothing\n")}
}
func main() {var ss Simplers := new(Simple)s.i = 1s1 := new(Rsimple)s1.i = 2ss = spanduan(ss)ss = s1panduan(ss)
}
练习 11.5 interfaces_ext.go:

a). 继续扩展程序,定义类型 Triangle,让它实现 AreaInterface 接口。通过计算一个特定三角形的面积来进行测试(三角形面积=0.5 * (底 * 高))

b). 定义一个新接口 PeriInterface,它有一个 Perimeter 方法。让 Square 实现这个接口,并通过一个 Square 示例来测试它。

package mainimport "fmt"type AreaInterface interface {calArea() float64
}
type PeriInterface interface {calPeri() float64
}
type Triangle struct {high  intwidth int
}func (a *Triangle) calArea() float64 {res := float64(a.high*a.width) / 2return res
}
func (a *Triangle) calPeri() float64 {res := float64(a.high+a.width) * 2return res
}type Square struct {high  intwidth int
}func (a *Square) calArea() float64 {res := float64(a.high * a.width)return res
}
func (a *Square) calPeri() float64 {res := float64(a.high+a.width) * 2return res
}
func main() {var a AreaInterfacevar b PeriInterfacet1 := Triangle{5, 10}t2 := Square{5, 10}a = &t1fmt.Print(a.calArea(), "\n")a = &t2fmt.Print(a.calArea(), "\n")b = &t1fmt.Print(b.calPeri(), "\n")b = &t2fmt.Print(b.calPeri(), "\n")}

在这里插入图片描述

练习 11.6 point_interfaces.go:

继续 10.3 中的练习 point_methods.go,定义接口 Magnitude,它有一个方法 Abs()。让 Point、Point3 及 Polar 实现此接口。通过接口类型变量使用方法做 point.go 中同样的事情。

package mainimport ("fmt""math"
)type Magnitude interface {Abs() float64Scale(flag float64)
}
type Point3d struct {x inty intz int
}func (p *Point3d) Abs() float64 {res := math.Sqrt(float64(p.x*p.x + p.y*p.y + p.z*p.z))return res
}
func (p *Point3d) Scale(flag float64) {lens := p.Abs()len_S := lens * flagcosx := float64(p.x) / lenscosy := float64(p.y) / lenscosz := float64(p.z) / lensp.x = int(len_S * cosx)p.y = int(len_S * cosy)p.z = int(len_S * cosz)}type Point2d struct {x inty int
}func (p *Point2d) Abs() float64 {res := math.Sqrt(float64(p.x*p.x + p.y*p.y))return res
}
func (p *Point2d) Scale(flag float64) {lens := p.Abs()len_S := lens * flagcosx := float64(p.x) / lenscosy := float64(p.y) / lensp.x = int(len_S * cosx)p.y = int(len_S * cosy)
}type Polar struct {l   float64cos float64
}func (p *Polar) Abs() float64 {return p.l
}
func (p *Polar) Scale(flag float64) {p.l *= flag
}
func main() {var m Magnitudep2 := new(Point2d)p2.x, p2.y = 5, 5p3 := new(Point3d)p3.x, p3.y, p3.z = 5, 5, 5p := new(Polar)p.l, p.cos = 5, 0.6m = p2res := m.Abs()fmt.Print(res, "\n")m.Scale(2)res = m.Abs()fmt.Print(res, "\n")m = p3res = m.Abs()fmt.Print(res, "\n")m.Scale(2)res = m.Abs()fmt.Print(res, "\n")m = pres = m.Abs()fmt.Print(res, "\n")m.Scale(2)res = m.Abs()fmt.Print(res, "\n")
}

在这里插入图片描述

练习 11.7 float_sort.go / float_sortmain.go:

类似 11.7 和示例 11.3/4,定义一个包 float64,并在包里定义类型 Float64Array,然后让它实现 Sorter 接口用来对 float64 数组进行排序。

另外提供如下方法:0

NewFloat64Array():创建一个包含 25 个元素的数组变量(参考 10.2 )
List():返回数组格式化后的字符串,并在 String() 方法中调用它,这样就不用显式地调用 List() 来打印数组(参考 10.7)
Fill():创建一个包含 10 个随机浮点数的数组(参考 4.5.2.6)
在主程序中新建一个此类型的变量,然后对它排序并进行测试。
FloatArray.go

package float64import ("math/rand""strconv""strings"
)type Float64Array struct {res []float64
}func (f *Float64Array) NewFloat64Array() {f.res = make([]float64, 25)
}
func (f *Float64Array) List() string {sb := strings.Builder{}for _, v := range f.res {sb.WriteString(strconv.FormatFloat(v, 'f', 10, 64) + "\t")}return sb.String()
}
func (f *Float64Array) String() string {return f.List()
}
func (f *Float64Array) Fill() {f.res = make([]float64, 10)for i, _ := range f.res {f.res[i] = rand.Float64()}
}
func (f Float64Array) Len() int {return len(f.res)
}
func (f Float64Array) Less(i, j int) bool {if f.res[i] > f.res[j] {return true} else {return false}
}
func (f Float64Array) Swap(i, j int) {temp := f.res[i]f.res[i] = f.res[j]f.res[j] = temp
}

main.go

package mainimport (float642 "awesomeProject/float64""fmt""sort"
)func main() {var ff float642.Float64Arrayff.Fill()fmt.Printf("%v\n", ff)var ff1 float642.Float64Arrayff1.NewFloat64Array()fmt.Printf("%v\n", ff1)sort.Sort(ff)fmt.Printf("%v\n", ff)}

结果:
在这里插入图片描述

练习 11.8 sort.go / sort_persons.go:

定义一个结构体 Person,它有两个字段:firstName 和 lastName,为 []Person 定义类型 Persons 。让 Persons 实现 Sorter 接口并进行测试。

package mainimport ("fmt""sort""strings"
)type Person struct {firstName stringlastName  string
}
type Persons []Personfunc (p Persons) String() string {sb := strings.Builder{}for i, _ := range p {sb.WriteString(p[i].firstName + " " + p[i].lastName + "\t")}return sb.String()
}
func (p Persons) Len() int {return len(p)
}
func (p Persons) Less(i, j int) bool {pi, pj := p[i], p[j]if strings.Compare(pi.firstName, pj.firstName) == 1 {return true} else if strings.Compare(pi.firstName, pj.firstName) == -1 {return false} else {if strings.Compare(pi.lastName, pj.lastName) == 1 {return true} else if strings.Compare(pi.lastName, pj.lastName) == -1 {return false} else {return false}}
}
func (p Persons) Swap(i, j int) {temp := p[i]p[i] = p[j]p[j] = temp
}
func main() {ps := Persons{Person{"asda", "ada"}, Person{"dasda", "adasdsa"}, Person{"dasdas", "dadasgdg"}, Person{"asda", "fdghfdghd"}}fmt.Printf("%v\n", ps)sort.Sort(ps)fmt.Printf("%v\n", ps)}

结果:
在这里插入图片描述

空接口

空接口或者最小接口 不包含任何方法,它对实现不做任何要求:

type Any interface {}
练习 11.9 simple_interface3.go:

继续练习 11.2,在它中添加一个 gI() 函数,它不再接受 Simpler 类型的参数,而是接受一个空接口参数。然后通过类型断言判断参数是否是 Simpler 类型。最后在 main 使用 gI() 取代 fI() 函数并调用它。确保你的代码足够安全。

package mainimport ("fmt"
)type any interface {
}func gl(a any) {if v, ok := a.(Simpler); ok {show(v)}
}type Simpler interface {get() intset(i int) Simpler
}func show(a Simpler) {fmt.Print(a.get(), "\n")a = a.set(10)fmt.Print(a.get(), "\n")}type ss struct {i int
}func (s ss) get() int {return s.i
}
func (s ss) set(i int) Simpler {s.i = ireturn s
}
func main() {var si Simplersi = ss{1}var a anya = sigl(a)
}
用空接口构建通用类型或包含不同类型变量的数组

们给空接口定一个别名类型 Element:type Element interface{}

然后定义一个容器类型的结构体 Vector,它包含一个 Element 类型元素的切片:

type Vector struct {a []Element
}

Vector 里能放任何类型的变量,因为任何类型都实现了空接口,实际上 Vector 里放的每个元素可以是不同类型的变量。我们为它定义一个 At() 方法用于返回第 i 个元素:

func (p *Vector) At(i int) Element {return p.a[i]
}
再定一个 Set() 方法用于设置第 i 个元素的值:func (p *Vector) Set(i int, e Element) {p.a[i] = e
}

Vector 中存储的所有元素都是 Element 类型,要得到它们的原始类型(unboxing:拆箱)需要用到类型断言。TODO:The compiler rejects assertions guaranteed to fail,类型断言总是在运行时才执行,因此它会产生运行时错误。

练习 11.10 min_interface.go / minmain.go:

仿照 11.7 中开发的 Sorter 接口,创建一个 Miner 接口并实现一些必要的操作。函数 Min() 接受一个 Miner 类型变量的集合,然后计算并返回集合中最小的元素。

package mainimport ("fmt""strings"
)type Element interface {
}
type Miner interface {Len() intSwap(i, j int)Less(i, j int) boolAt(i int) ElementSet(i int, e Element)
}
type Vector struct {a []Element
}func (p *Vector) Len() int {return len(p.a)
}// 不同类型sting>float64>float32>int
func (p *Vector) Less(i, j int) bool {pi, pj := p.a[i], p.a[j]switch pi.(type) {case int:switch pj.(type) {case int:piv, pjv := pi.(int), pj.(int)if piv > pjv {return true} else {return false}case float32:return falsecase float64:return falsecase string:return false}case string:switch pj.(type) {case string:piv, pjv := pi.(string), pj.(string)if strings.Compare(piv, pjv) == 1 {return true} else {return false}case int:return truecase float64:return truecase float32:return true}case float64:switch pj.(type) {case float64:piv, pjv := pi.(float64), pj.(float64)if piv > pjv {return true} else {return false}case string:return falsecase int:return truecase float32:return true}case float32:switch pj.(type) {case float32:piv, pjv := pi.(float32), pj.(float32)if piv > pjv {return true} else {return false}case string:return falsecase int:return truecase float64:return false}}return false
}
func (p *Vector) Swap(i, j int) {pi, pj := p.a[i], p.a[j]p.Set(i, pj)p.Set(j, pi)
}
func (p *Vector) At(i int) Element {return p.a[i]
}
func (p *Vector) Set(i int, e Element) {p.a[i] = e
}
func Sort(data Miner) {for pass := 1; pass < data.Len(); pass++ {for i := 0; i < data.Len()-pass; i++ {if data.Less(i+1, i) {data.Swap(i, i+1)}}}
}
func Min(data Miner) Element {Sort(data)lens := data.Len()return data.At(lens - 1)
}
func Max(data Miner) Element {Sort(data)return data.At(0)
}
func main() {v := Vector{[]Element{123, 464, 13.01, 15430.154, "adsdsa", "adadasda", "tyurueueue"}}res := Min(&v)switch res.(type) {case int:fmt.Print(res.(int))case string:fmt.Print(res.(string))case float64:fmt.Print(res.(float64))case float32:fmt.Print(res.(float32))}res1 := Max(&v)switch res1.(type) {case int:fmt.Print(res1.(int))case string:fmt.Print(res1.(string))case float64:fmt.Print(res1.(float64))case float32:fmt.Print(res1.(float32))}
}

结果:
在这里插入图片描述

反射

两个简单的函数,reflect.TypeOf 和 reflect.ValueOf,返回被检查对象的类型和值。他们的返回值分别为reflect.Type 和 reflect.Value类型。有许多方法用于检查和操作它们。 Type 和 Value 都有 Kind() 方法返回一个常量来表示类型:Uint、Float64、Slice 等等。同样 Value 有叫做 Int() 和 Float() 的方法可以获取存储在内部的值(跟 int64 和 float64 一样)Kind() 总是返回底层类型:
例子:

func main() {type MyInt intvar m MyInt = 5v := reflect.ValueOf(m)fmt.Println(v.Kind())fmt.Println(v.Type())fmt.Println(v.Int())}

结果:
在这里插入图片描述

通过反射修改(设置)值

假设我们要把 x 的值改为 3.1415。Value 有一些方法可以完成这个任务。首先需要判断是否可设置,是否可设置是 Value 的一个属性,并且不是所有的反射值都有这个属性:可以使用 CanSet() 方法测试是否可设置。当 v := reflect.ValueOf(x) 函数通过传递一个 x 拷贝创建了 v,那么 v 的改变并不能更改原始的 x。要想 v 的更改能作用到 x,那就必须传递 x 的地址 v = reflect.ValueOf(&x)。通过 Type() 我们看到 v 现在的类型是 *float64 并且仍然是不可设置的。要想让其可设置我们需要使用 Elem() 函数,这间接地使用指针:v = v.Elem()现在 v.CanSet() 返回 true 并且v.SetFloat(3.1415) 设置成功了

package mainimport ("fmt""reflect"
)func main() {var x float64 = 3.4v := reflect.ValueOf(x)// setting a value:// v.SetFloat(3.1415) // Error: will panic: reflect.Value.SetFloat using unaddressable valuefmt.Println("settability of v:", v.CanSet())v = reflect.ValueOf(&x) // Note: take the address of x.fmt.Println("type of v:", v.Type())fmt.Println("settability of v:", v.CanSet())v = v.Elem()fmt.Println("The Elem of v is: ", v)fmt.Println("settability of v:", v.CanSet())v.SetFloat(3.1415) // this works!fmt.Println(v.Interface())fmt.Println(v)
}

结果:
在这里插入图片描述

反射结构

有些时候需要反射一个结构类型。NumField() 方法返回结构内的字段数量;通过一个 for 循环用索引取得每个字段的值 Field(i)。但是如果尝试更改一个值,需将
被导出字段的首字母大写设置为大写。

package mainimport ("fmt""reflect""strconv"
)type test struct {s1, s2, s3 string
}
type Test struct {S1, S2, S3 string
}
type any interface {
}func main() {var any1 anyany1 = test{"adas", "adasd", "dasdad"}any3 := Test{"huw", "adhjs", "wequwe"}value := reflect.ValueOf(any1)value1 := reflect.ValueOf(&any3).Elem()for i := 0; i < value.NumField(); i++ {fmt.Printf("Field %d: %v\n", i, value.Field(i))fmt.Printf("Field %d: %v\n", i, value1.Field(i).Interface())value1.Field(i).SetString(strconv.Itoa(i))}for i := 0; i < value.NumField(); i++ {fmt.Printf("Field %d: %v\n", i, value1.Field(i))}
}

在这里插入图片描述

练习 11.11:map_function_interface.go:

在练习 7.13 中我们定义了一个 map() 函数来使用 int 切片 (map_function.go)。

通过空接口和类型断言,现在我们可以写一个可以应用于许多类型的泛型的 map() 函数,为 int 和 string 构建一个把 int 值加倍和将字符串值与其自身连接(译者注:即 “abc” 变成 “abcabc” )的 map() 函数 mapFunc()。

提示:为了可读性可以定义一个 interface{} 的别名,比如:type obj interface{}。

package mainimport "fmt"type any interface{}func main() {// define a generic lambda function mf:mf := func(i any) any {switch i.(type) {case int:return i.(int) * i.(int)case string:return i.(string) + i.(string)}return i}isl := []any{0, 1, 2, 3, 4, 5}res1 := mapFunc(mf, isl)for _, v := range res1 {fmt.Println(v)}println()ssl := []any{"0", "1", "2", "3", "4", "5"}res2 := mapFunc(mf, ssl)for _, v := range res2 {fmt.Println(v)}
}func mapFunc(mf func(any) any, list []any) []any {result := make([]any, len(list))for ix, v := range list {result[ix] = mf(v)}return result
}

在这里插入图片描述

练习 11.12:map_function_interface_var.go:

稍微改变练习 11.11,允许 mapFunc() 接收不定数量的 items。

package mainimport "fmt"type any interface{}func main() {// define a generic lambda function mf:mf := func(i any) any {switch i.(type) {case int:return i.(int) * i.(int)case string:return i.(string) + i.(string)}return i}res1 := mapFunc(mf, 1, 2, 3, 4, 5, 6, 7)for _, v := range res1 {fmt.Println(v)}println()res2 := mapFunc(mf, "1", "2", "3", "4", "5", "6")for _, v := range res2 {fmt.Println(v)}
}func mapFunc(mf func(any) any, list ...any) []any {result := make([]any, len(list))for ix, v := range list {result[ix] = mf(v)}return result
}

在这里插入图片描述

练习 11.13:main_stack.go—stack/stack_general.go:

在练习 10.16 和 10.17 中我们开发了一些栈结构类型。但是它们被限制为某种固定的内建类型。现在用一个元素类型是 interface{}(空接口)的切片开发一个通用的栈类型。

实现下面的栈方法:

Len() int
IsEmpty() bool
Push(x interface{})
Pop() (interface{}, error)
Pop() 改变栈并返回最顶部的元素;Top() 只返回最顶部元素。

在主程序中构建一个充满不同类型元素的栈,然后弹出并打印所有元素的值。

package mainimport "fmt"type any interface{}
type tank struct {val []anylen int
}func (this *tank) Len() int {return this.len
}
func (this *tank) IsEmpty() bool {if this.len == 0 {return true} else {}
}
func (this *tank) Push(x any) {this.val = append(this.val, x)this.len++
}
func (this *tank) Pop() any {res := this.val[this.len-1]this.len--return res}
func main() {var t tankfmt.Println(t.IsEmpty())fmt.Println(t.Len())t.Push("asdasd")t.Push(1)t.Push(1.4546)t.Push(rune('a'))fmt.Println(t.IsEmpty())fmt.Println(t.Len())for i := 0; i < len(t.val); i++ {fmt.Println(t.Pop())}
}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/fJRGWf9X.shtml

相关文章

多设备monkey测试工具_基于Tkinter GUI操作

V1.0版本 先看下效果吧&#xff1a; 简单的介绍下&#xff1a; 1.设备列表区域&#xff1a;用于展示当前连接的所有设备 2.monkey参数区域&#xff1a;用于显示即将执行的monkey参数 3.日志区域&#xff1a;用于显示必要日志&#xff08;其实没啥卵用&#xff0c;就是看着高…

Python日常小技巧(持续更新中)

目录 快速定位元组内容对字典进行排序json的获取(dumps,dump,loads,load)查找字典中相同的key统计列表中元素的个数字典按输入顺序输出历史记录的存储对有多个分割符的字符串进行分割对文件中的时间格式进行转换 字符串的居中&#xff0c;左右对齐列表并行/串行计算字符串判断是…

Flink 学习三 Flink 流 process function API

Flink 学习三 Flink 流&process function API 1.Flink 多流操作 1.1.split 分流 (deprecated) 把一个数据流根据数据分成多个数据流 1.2 版本后移除 1.2.分流操作 (使用侧流输出) public class _02_SplitStream {public static void main(String[] args) throws Excep…

基于Unity3D实现的牙医病人小游戏【100011407】

1 总体设计 1&#xff09;基本技术路线 运用面向对象的设计理念&#xff0c;设计了病人类&#xff0c;牙医类&#xff0c;候诊椅类&#xff0c;诊疗椅类等&#xff0c;通过对这些类的封装&#xff0c;创立各个类的对象&#xff0c;并调用类的成员函数。 2&#xff09;总体结…

Java IO,BIO、NIO、AIO

操作系统中的 I/O 以上是 Java 对操作系统的各种 IO 模型的封装&#xff0c;【文件的输入、输出】在文件处理时&#xff0c;其实依赖操作系统层面的 IO 操作实现的。【把磁盘的数据读到内存种】操作系统中的 IO 有 5 种&#xff1a; 阻塞、 非阻塞、【轮询】 异步、 IO复…

TensorFlow2.0学习笔记-3.模型训练

3.模型训练 3.1.Keras版本模型训练 • 构建模型&#xff08;顺序模型、函数式模型、子类模型&#xff09; • 模型训练&#xff1a; model.fit() • 模型验证&#xff1a; model.evaluate() • 模型预测&#xff1a; model.predict() • 使用样本加权和类别加权 回调函数 •…

sql注入学习

提示&#xff1a;萌新学习路程的记录型文章&#xff0c;有错误的地方欢迎大佬们指正。 文章目录 前言一、SQLi-Labs1、SQLi-Labs下载、安装&#xff08;环境搭建)(1) 首先下载解压并移动sqli-labs(2) 找到sql-connections下的db-creds.inc进行修改(3) 打开网页&#xff1a;http…

从客户端中检测到有潜在危险的 request.form值[解决方法]

当页面编辑或运行提交时,出现“从客户端中检测到有潜在危险的request.form值”问题,该怎么办呢?如下图所示: 下面博主汇总出现这种错误的几种解决方法:问题原因:由于在asp.net中,Request提交时出现有html代码或javascript等字符串时,程序系统会认为其具有潜在危险的值。…

sadadas

dasdasdasdasdasd

python_day3_集合与运算/文件读写、修改详解/字符编码转换/函数和函数式编程(return/参数详解/局部变量与全局变量/递归/高阶函数)

Python_集合与运算/文件读写、修改详解/字符编码详解/函数和函数式编程/函数式编程之参数/局部变量与全局变量/递归/高阶函数 在这里得感谢&#xff0c;老师Alex金角大王(路飞学城IT) Python(给兄弟们挂个&#x1f517;) >_<…因为有的是自己理解&#xff0c;如有错误&a…

svn添加新项目的步骤

1.服务端给一个地址&#xff1a;拉取代码 2.上传代码&#xff08;不含没有module的build文件夹和以下文件夹&#xff09;

项目新添加页面svn上传

你项目当中新添加了页面上传SVN&#xff0c;需要先把新添加的页面Add到SVN上&#xff0c; 右击新添加的页面出现TortoiseSVN — Add&#xff0c;然后上传整个项目就可以了&#xff0c;SVN上就有新添加的页面了。 如下图

Eclipse用SVN上传新项目

首先右击项目–>team --> share project 选择repository为svn–>点击next 使用已有的资源库的位置&#xff0c;如下图所示&#xff1a; 使用项目名称作为文件夹名 --> 点击Finish --> 输入用户名和密码(此步不一定每个人都有)&#xff0c;如下图所示&#xff1a…

IDEA添加新项目到SVN

1.打开IDEA &#xff0c;上面工具栏选择VCS 选择把项目交给SVN管理 2.选择SVN 3、右键项目选择如下 4.点击绿色的号&#xff0c;选择一个SVN仓库的地址&#xff0c;下面可以选择上传到SVN仓库的目录格式&#xff0c;然后点击Share 5.默认1.8 6.右键项目选择-->Subversion--…

项目上传到SVN

步骤1、首先在服务器上安装svn。 步骤2、然后找到svn 选择VisualSVN Server Manager 在Repositories下新建Repository name 步骤3、在MyEclipse中右击项目&#xff0c;Team–>Share Project–>SVN–>创建新的资源位置或使用已有的资源位置&#xff08;最好新建&#…

idea上传新项目至svn仓库

linux下安装svn服务器&#xff0c;idea上传新项目 linux下安装svn服务器,配置svn仓库 就不写了,百度一大把 导入项目: 点击号 linux下svn://开头,输入svn服务器创建的仓库地址,也可连接http:// 输入svn仓库配置的账号.密码 导入

Eclipse中SVN上传项目

上传新项目到SVN服务器 选中你要上传的项目&#xff0c;右键-->Team-->Share Project&#xff0c;选中SVN-->Next。 前提是已经安装SVN插件&#xff1a;https://blog.csdn.net/weixin_44306005/article/details/95487732 如图所示进行下一步操作&#xff1a; 如图所…

IDEA使用SVN上传项目

1、设置SVN 2、在settings→Version Control中可以改变版本控制 3、右键项目选择如下 4、添加仓库地址 5、点击share提交 6、文件颜色由红变绿 7、右键选择commit 一路选择commit 7、如果在IDEA中上传太慢,可以选择在项目文件中直接使用SVN上传 PS&#xff1a;如果账号有问题,…

IDEA如何将上传项目到SVN

1.打开IDEA &#xff0c;上面工具栏选择VCS 选择把项目交给SVN管理 2.选择SVN 3、选择SVN管理后可以看到项目变砖红色颜色 4、右键项目选择如下 5、点击绿色的号&#xff0c;选择一个SVN仓库的地址&#xff0c;下面可以选择上传到SVN仓库的目录格式&#xff0c;然后点击Shard…

linuxsvn服务器导入项目,linux svn 导入项目

linux svn 导入项目 内容精选 换一换 用于将其它云端仓库导入到代码托管服务中&#xff0c;也可以将代码托管服务中一个区域的仓库导入到另一个区域(异地备份)&#xff0c;导入后的仓库与源仓库彼此独立。在代码托管服务控制台导入外部仓库的步骤如下&#xff1a;外部仓库可以是…