在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

三十分鐘入門基礎Go Java小子版

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-08-12 14:32 ? 次閱讀

前言

Go語言定義

Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開發的一種靜態、強類型、編譯型語言。Go 語言語法與 C 相近,但功能上有:內存安全,GC,結構形態及 CSP-style 并發計算。

適用范圍

本篇文章適用于學習過其他面向對象語言(Java、Php),但沒有學過Go語言的初學者。文章主要從Go與Java功能上的對比來闡述Go語言的基礎語法、面向對象編程、并發與錯誤四個方面。

一、基礎語法

Go語言的基礎語法與常規的編程語言基本類似,所不同的有聲明變量的方式,數組、切片、字典的概念及功能與Java不太相同,不過Java中這些數據結構都可以通過類比功能的方式在Go中使用。

1.1 變量、常量、nil與零值、方法、包、可見性、指針

1.1.1 變量聲明

Go語言中有兩種方式

1.使用var關鍵字聲明,且需要注意的是,與大多數強類型語言不同,Go語言的聲明變量類型位于變量名稱的后面。Go語句結束不需要分號。

var num int

var result string = "this is result"

2.使用:=賦值。

num := 3 等同于 var num int = 3

其中變量的類型會根據右側的值進行匹配,例如"3"會匹配為int,"3.0"會匹配為float64,"result"會匹配為string。

1.1.2 常量聲明

使用const來聲明一個常量,一個常量在聲明后不可改變。

const laugh string = "go"

1.1.3 nil與零值

只聲明未賦值的變量,其值為nil。類似于java中的“null”

沒有明確初始值的變量聲明會被賦予它們的 零值

零值是:

數值類型為 0,

布爾類型為 false,

字符串為 ""(空字符串)。

1.1.4 方法、包

Go中方法的定義

使用func關鍵字來定義一個方法,后面跟方法名,然后是參數,返回值(如果有的話,沒有返回值則不寫)。

func MethodName(p1 Parm, p2 Parm) int{}

//學習一個語言應該從Hello World開始!
package main

import "fmt"

func main() {
	fmt.Println("Hello World!")// Hello World!
    fmt.Println(add(3, 5)) //8
    var sum = add(3, 5)
}

func add(a int, b int) int{
    return a+b;
}

多個返回值

Go 函數與其他編程語言一大不同之處在于支持多返回值,這在處理程序出錯的時候非常有用。例如,如果上述 add 函數只支持非負整數相加,傳入負數則會報錯。

//返回值只定義了類型 沒有定義返回參數
func add(a, b int) (int, error) {
    if a < 0 || b < 0 {
        err := errors.New("只支持非負整數相加")
        return 0, err
    }
    a *= 2
    b *= 3
    return a + b, nil
}

//返回值還定義了參數 這樣可以直接return 并且定義的參數可以直接使用 return時只會返回這兩個參數
func add1(a, b int) (z int, err error) {
    if a < 0 || b < 0 {
        err := errors.New("只支持非負整數相加")
        return   //實際返回0 err 因為z只定義沒有賦值 則nil值為0
    }
    a *= 2
    b *= 3
    z = a + b
    return //返回 z err
}

func main()  {
    x, y := -1, 2
    z, err := add(x, y)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Printf("add(%d, %d) = %dn", x, y, z)
}

變長參數

func myfunc(numbers ...int) {
    for _, number := range numbers {
        fmt.Println(number)
    }
}

slice := []int{1, 2, 3, 4, 5}
//使用...將slice打碎傳入
myfunc(slice...)

包與可見性

在 Go 語言中,無論是變量、函數還是類屬性和成員方法,它們的可見性都是以包為維度的,而不是類似傳統面向編程那樣,類屬性和成員方法的可見性封裝在所屬的類中,然后通過 private、protected 和 public 這些關鍵字來修飾其可見性。

Go 語言沒有提供這些關鍵字,不管是變量、函數,還是自定義類的屬性和成員方法,它們的可見性都是根據其首字母的大小寫來決定的,如果變量名、屬性名、函數名或方法名首字母大寫,就可以在包外直接訪問這些變量、屬性、函數和方法,否則只能在包內訪問,因此 Go 語言類屬性和成員方法的可見性都是包一級的,而不是類一級的。

假如說一個名為domain的文件夾下有3個.go文件,則三個文件中的package都應為domain,其中程序的入口main方法所在的文件,包為main

//定義了此文件屬于 main 包
package main

//通過import導入標注庫中包
import "fmt"

func main() {
	fmt.Println("Hello World!")// Hello World!
    fmt.Println(add(3, 5)) //8
    var sum = add(3, 5)
}

func add(a int, b int) int{
    return a+b;
}

1.1.5 指針

對于學過C語言來說,指針還是比較熟悉的,我所理解的指針,其實就是一個在內存中實際的16進制的地址值,引用變量的值通過此地址去內存中取出對應的真實值。

func main() {
    i := 0
    //使用&來傳入地址
    fmt.Println(&i) //0xc00000c054
    
    var a, b int = 3 ,4
    //傳入 0xc00000a089 0xc00000a090
    fmt.Println(add(&a, &b)) 
}

//使用*來聲明一個指針類型的參數與使用指針
func add(a *int, b *int)int{
    //接收到 0xc00000a089 0xc00000a090
    //前往 0xc00000a089位置查找具體數據 并取賦給x
    x := *a
    //前往 0xc00000a090位置查找具體數據 并取賦給y
    y := *b
	return x+y
}

1.2 條件、循環、分支

1.2.1 條件

與Java語言的if基本相同

// if
if condition { 
    // do something 
}

// if...else...
if condition { 
    // do something 
} else {
    // do something 
}

// if...else if...else...
if condition1 { 
    // do something 
} else if condition2 {
    // do something else 
} else {
    // catch-all or default 
}

1.2.2 循環

sum := 0 

//普通for循環
for i := 1; i <= 100; i++ { 
    sum += i 
}

//無限循環
for{
    sum++
    if sum = 100{
        break;
    }
}

//帶條件的循環
for res := sum+1; sum < 15{
    sum++
    res++
}

//使用kv循環一個map或一個數組  k為索引或鍵值 v為值 k、v不需要時可以用_帶替
for k, v := range a {
    fmt.Println(k, v)
}

1.2.3 分支

score := 100
switch score {
case 90, 100:
    fmt.Println("Grade: A")
case 80:
    fmt.Println("Grade: B")
case 70:
    fmt.Println("Grade: C")
case 65:
    fmt.Println("Grade: D")
default:
    fmt.Println("Grade: F")
}

1.3 數組、切片、字典

1.3.1 數組

數組功能與Java語言類似,都是長度不可變,并且可以使用多維數組,也可以通過arrays[i]來存儲或獲取值。

//聲明
var nums [3]int 
//聲明并初始化
var nums = [3]int{1,2,3} <==?> nums:=[3]int{1,2,3}

//使用
for sum := 0, i := 0;i

數組使用較為簡單,但是存在著難以解決的問題:長度固定

例如當我們在程序中需要一個數據結構來存儲獲取到的所有用戶,因為用戶數量是會隨著時間變化的,但是數組其長度卻不可改變,所以數組并不適合存儲長度會發生改變的數據。因此在Go語言中通過使用切片來解決以上問題。

1.3.2 切片

切片相比于Java來說是一種全新的概念。在Java中,對于不定長的數據存儲結構,可以使用List接口來完成操作,例如有ArrayList與LinkList,這些接口可以實現數據的隨時添加與獲取,并沒有對長度進行限制。但是在Go中不存在這樣的接口,而是通過切片(Slice)來完成不定長的數據長度存儲

切片與數組最大的不同就是切片不用聲明長度。但是切片與數組并非毫無關系,數組可以看作是切片的底層數組,而切片則可以看作是數組某個連續片段的引用。切片可以只使用數組的一部分元素或者整個數組來創建,甚至可以創建一個比所基于的數組還要大的切片:

長度、容量

切片的長度就是它所包含的元素個數。

切片的容量是從它的第一個元素開始數,到其底層數組元素末尾的個數。

切片 s 的長度和容量可通過表達式 len(s) 和 cap(s) 來獲取。

切片的長度從功能上類比與Java中List的size(),即通過len(slice)來感知切片的長度,即可對len(slice)進行循環,來動態控制切片內的具體內容。切片的容量在實際開發中運用不多,了解其概念即可。

創建切片

//聲明一個數組
var nums =[3]int{1, 2, 3}
//0.直接聲明
var slice =[]int{0, 1, 2}

//1.從數組中引用切片 其中a:b是指包括a但不包括b
var slice1 = nums[0:2] //{1,2}
//如果不寫的則默認為0(左邊)或最大值(右邊)
var slice2 = slice1[:2] <==?> var slice2 = slice1[0:] <==?>var slice2 = slice1[:]

//2.使用make創建Slice 其中int為切片類型,4為其長度,5為容量
slice3 := make([]int, 5)
slice4 := make([]int, 4, 5)

動態操作切片

//使用append向切片中動態的添加元素
func append(s []T, vs ...T) []T

slice5 := make([]int, 4, 5) //{0, 0, 0, 0}
slice5 = append(slice5, 1) //{0,0,0,0,1}

//刪除第一個0
sliece5 = slice5[1:]

切片的常用場景

模擬上述提到的問題使用切片解決方案

//聲明切片
var userIds = []int{}
//模擬獲取所有用戶ID
for i := 0; i< 100{
    userIds = append(userIdS, i);
    i++;
}
//對用戶信息進行處理
for k,v := range userIds{
    userIds[k] = v++
}

1.3.3 字典

字典也可稱為 ‘鍵值對’ 或 ‘key-value’,是一種常用的數據結構,Java中有各種Map接口,常用的有HashMap等。在Go中通過使用字典來實現鍵值對的存儲,字典是無序的,所以不會根據添加順序來保證數據的順序。

字典的聲明與初始化

//string為鍵類型,int為值類型
maps := map[string]int{
  "java" : 1,
  "go" : 2,
  "python" : 3,
}

//還可以通過make來創建字典 100為其初始容量 超出可擴容
maps = make(map[string]int, 100)

字典的使用場景

//直接使用
fmt.Println(maps["java"]) //1

//賦值
maps["go"] = 4

//取值 同時判斷map中是否存在該鍵 ok為bool型
value, ok := maps["one"] 
if ok { // 找到了
  // 處理找到的value 
}

//刪除
delete(testMap, "four")

二、面向對象編程

2.1 Go語言中的類

眾所周知,在面向對象的語言中,一個類應該具有屬性、構造方法、成員方法三種結構,Go語言也不例外。

2.1.1 類的聲明與初始化

Go語言中并沒有明確的類的概念,只有struct關鍵字可以從功能上類比為 面向對象語言中的“類” 。比如要定義一個學生類,可以這么做:

type Student struct {
    id int
    name string
    male bool
    score float64
}//定義了一個學生類,屬性有id name等,每個屬性的類型都在其后面

//定義學生類的構造方法
func NewStudent(id uint, name string, male bool, score float64) *Student {
    return &Student{id, name, male, score}
}

//實例化一個類對象
student := NewStudent(1, "學院君", 100)
fmt.Println(student)

2.1.2 成員方法

Go中的成員方法聲明與其他語言不大相同。以Student類為例,

//在方法名前,添加對應的類,即可認為改方法為該類的成員方法。
func (s Student) GetName() string  {
    return s.name
}

//注意這里的Student是帶了*的 這是因為在方法傳值過程中 存在著值傳遞與引用傳遞 即指針的概念 當使用值傳遞時 編譯器會為該參數創建一個副本傳入 因此如果對副本進行修改其實是不生效的 因為在執行完此方法后該副本會被銷毀 所以此處應該是用*Student 將要修改的對象指針傳入 修改值才能起作用
func (s *Student) SetName(name string) {
    //這里其實是應該使用(*s).name = name,因為對于一個地址來說 其屬性是沒意義的 不過這樣使用也是可以的 因為編譯器會幫我們自動轉換
    s.name = name
}

2.2 接口

接口在 Go 語言中有著至關重要的地位,如果說 goroutine 和 channel 是支撐起 Go 語言并發模型的基石,那么接口就是 Go 語言整個類型系統的基石。Go 語言的接口不單單只是接口,下面就讓我們一步步來探索 Go 語言的接口特性。

2.2.1 傳統侵入式接口實現

和類的實現相似,Go 語言的接口和其他語言中提供的接口概念完全不同。以 Java、PHP 為例,接口主要作為不同類之間的契約(Contract)存在,對契約的實現是強制的,體現在具體的細節上就是如果一個類實現了某個接口,就必須實現該接口聲明的所有方法,這個叫「履行契約」:

// 聲明一個'iTemplate'接口
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}


// 實現接口
// 下面的寫法是正確的
class Template implements iTemplate
{
    private $vars = array();

    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }

    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }

        return $template;
    }
}

這個時候,如果有另外有一個接口 iTemplate2 聲明了與 iTemplate 完全一樣的接口方法,甚至名字也叫 iTemplate,只不過位于不同的命名空間下,編譯器也會認為上面的類 Template 只實現了 iTemplate 而沒有實現 iTemplate2 接口。

這在我們之前的認知中是理所當然的,無論是類與類之間的繼承,還是類與接口之間的實現,在 Java、PHP 這種單繼承語言中,存在著嚴格的層級關系,一個類只能直接繼承自一個父類,一個類也只能實現指定的接口,如果沒有顯式聲明繼承自某個父類或者實現某個接口,那么這個類就與該父類或者該接口沒有任何關系。

我們把這種接口稱為侵入式接口,所謂「侵入式」指的是實現類必須明確聲明自己實現了某個接口。這種實現方式雖然足夠明確和簡單明了,但也存在一些問題,尤其是在設計標準庫的時候,因為標準庫必然涉及到接口設計,接口的需求方是業務實現類,只有具體編寫業務實現類的時候才知道需要定義哪些方法,而在此之前,標準庫的接口就已經設計好了,我們要么按照約定好的接口進行實現,如果沒有合適的接口需要自己去設計,這里的問題就是接口的設計和業務的實現是分離的,接口的設計者并不能總是預判到業務方要實現哪些功能,這就造成了設計與實現的脫節。

接口的過分設計會導致某些聲明的方法實現類完全不需要,如果設計的太簡單又會導致無法滿足業務的需求,這確實是一個問題,而且脫離了用戶使用場景討論這些并沒有意義,以 PHP 自帶的 SessionHandlerInterface 接口為例,該接口聲明的接口方法如下:

SessionHandlerInterface {
    /* 方法 */
    abstract public close ( void ) : bool
    abstract public destroy ( string $session_id ) : bool
    abstract public gc ( int $maxlifetime ) : int
    abstract public open ( string $save_path , string $session_name ) : bool
    abstract public read ( string $session_id ) : string
    abstract public write ( string $session_id , string $session_data ) : bool
}

用戶自定義的 Session 管理器需要實現該接口,也就是要實現該接口聲明的所有方法,但是實際在做業務開發的時候,某些方法其實并不需要實現,比如如果我們基于 Redis 或 Memcached 作為 Session 存儲器的話,它們自身就包含了過期回收機制,所以 gc 方法根本不需要實現,又比如 close 方法對于大部分驅動來說,也是沒有什么意義的。

正是因為這種不合理的設計,所以在編寫 PHP 類庫中的每個接口時都需要糾結以下兩個問題(Java 也類似):

一個接口需要聲明哪些接口方法?

如果多個類實現了相同的接口方法,應該如何設計接口?比如上面這個 SessionHandlerInterface,有沒有必要拆分成多個更細分的接口,以適應不同實現類的需要?

接下我們來看看 Go 語言的接口是如何避免這些問題的。

2.2.2 Go 語言的接口實現

在 Go 語言中,類對接口的實現和子類對父類的繼承一樣,并沒有提供類似 implement 這種關鍵字顯式聲明該類實現了哪個接口,一個類只要實現了某個接口要求的所有方法,我們就說這個類實現了該接口

例如,我們定義了一個 File 類,并實現了 Read()、Write()、Seek()、Close() 四個方法:

type File struct { 
    // ...
}

func (f *File) Read(buf []byte) (n int, err error) 
func (f *File) Write(buf []byte) (n int, err error) 
func (f *File) Seek(off int64, whence int) (pos int64, err error) 
func (f *File) Close() error

假設我們有如下接口(Go 語言通過關鍵字 interface 來聲明接口,以示和結構體類型的區別,花括號內包含的是待實現的方法集合):

type IFile interface { 
    Read(buf []byte) (n int, err error) 
    Write(buf []byte) (n int, err error) 
    Seek(off int64, whence int) (pos int64, err error) 
    Close() error 
}

type IReader interface { 
    Read(buf []byte) (n int, err error) 
}

type IWriter interface { 
    Write(buf []byte) (n int, err error) 
}

type ICloser interface { 
    Close() error 
}

盡管 File 類并沒有顯式實現這些接口,甚至根本不知道這些接口的存在,但是我們說 File 類實現了這些接口,因為 File 類實現了上述所有接口聲明的方法。當一個類的成員方法集合包含了某個接口聲明的所有方法,換句話說,如果一個接口的方法集合是某個類成員方法集合的子集,我們就認為該類實現了這個接口。

與 Java、PHP 相對,我們把 Go 語言的這種接口稱作非侵入式接口,因為類與接口的實現關系不是通過顯式聲明,而是系統根據兩者的方法集合進行判斷。這樣做有兩個好處:

其一,Go 語言的標準庫不需要繪制類庫的繼承/實現樹圖,在 Go 語言中,類的繼承樹并無意義,你只需要知道這個類實現了哪些方法,每個方法是干什么的就足夠了。

其二,定義接口的時候,只需要關心自己應該提供哪些方法即可,不用再糾結接口需要拆得多細才合理,也不需要為了實現某個接口而引入接口所在的包,接口由使用方按需定義,不用事先設計,也不用考慮之前是否有其他模塊定義過類似接口。

這樣一來,就完美地避免了傳統面向對象編程中的接口設計問題。

三、并發與多線程

3.1 Goroutine

對于任何一個優秀的語言來說,并發處理的能力都是決定其優劣的關鍵。在Go語言中,通過Goroutine來實現并發的處理。

func say(s string) {
	fmt.Println(s)
}

func main() {
    //通過 go 關鍵字新開一個協程
	go say("world")
	say("hello")
}

Go語言中沒有像Java那么多的鎖來限制資源同時訪問,只提供了Mutex來進行同步操作。

//給類SafeCounter添加鎖
type SafeCounter struct {
	v   map[string]int
	mux sync.Mutex
}

// Inc 增加給定 key 的計數器的值。
func (c *SafeCounter) Inc(key string) {
    //給該對象上鎖
	c.mux.Lock()
	// Lock 之后同一時刻只有一個 goroutine 能訪問 c.v
	c.v[key]++
    //解鎖
	c.mux.Unlock()
}

3.2 Channel

多協程之間通過Channel進行通信,從功能上可以類比為Java的volatile關鍵字。

ch := make(chan int) 聲明一個int型的Channel,兩個協程之間可以通過ch進行int數據通信。

通過Channel進行數據傳輸。

ch 
package main

import "fmt"

func sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c 

四、錯誤處理

4.1 error

Go 語言錯誤處理機制非常簡單明了,不需要學習了解復雜的概念、函數和類型,Go 語言為錯誤處理定義了一個標準模式,即 error 接口,該接口的定義非常簡單:

type error interface { 
    Error() string 
}

其中只聲明了一個 Error() 方法,用于返回字符串類型的錯誤消息。對于大多數函數或類方法,如果要返回錯誤,基本都可以定義成如下模式 —— 將錯誤類型作為第二個參數返回:

func Foo(param int) (n int, err error) { 
    // ...
}

然后在調用返回錯誤信息的函數/方法時,按照如下「衛述語句」模板編寫處理代碼即可:

n, err := Foo(0)

if err != nil { 
    // 錯誤處理 
} else{
    // 使用返回值 n 
}

非常簡潔優雅。

4.2 defer

defer用于確保一個方法執行完成之后,無論執行結果是否成功,都要執行defer中的語句。類似于Java中的try..catch..finally用法。例如在文件處理中,無論結果是否成功,都要關閉文件流。

func ReadFile(filename string) ([]byte, error) {
    f, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    //無論結果如何 都要關閉文件流
    defer f.Close()

    var n int64 = bytes.MinRead

    if fi, err := f.Stat(); err == nil {
        if size := fi.Size() + bytes.MinRead; size > n {
            n = size
        }
    }
    return readAll(f, n)
}

4.3 panic

Go語言中沒有太多的異常類,不像Java一樣有Error、Exception等錯誤類型,當然也沒有try..catch語句。

Panic(恐慌),意味在程序運行中出現了錯誤,如果該錯誤未被捕獲的話,就會造成系統崩潰退出。例如一個簡單的panic:a := 1/0。

就會引發panic: integer divide by zero。

wKgaoma5rIOAYKpLAAQ04GlurC8295.png

其中第一行表示出問題的協程,第二行是問題代碼所在的包和函數,第三行是問題代碼的具體位置,最后一行則是程序的退出狀態,通過這些信息,可以幫助你快速定位問題并予以解決。

4.4 recover

當有可以預見的錯誤時,又不希望程序崩潰退出,可以使用recover()語句來捕獲未處理的panic。recover應當放在defer語句中,且該語句應該在方法中前部,避免未能執行到defer語句時就引發了系統異常退出。

package main

import (
    "fmt"
)

func divide() {
    //通過defer,確保該方法只要執行完畢都要執行該匿名方法
    defer func() {
        //進行異常捕獲
        if err := recover(); err != nil {
            fmt.Printf("Runtime panic caught: %vn", err)
        }
    }()

    var i = 1
    var j = 0
    k := i / j
    fmt.Printf("%d / %d = %dn", i, j, k)
}

func main() {
    divide()
    fmt.Println("divide 方法調用完畢,回到 main 函數")
}
wKgZoma5rISAAfXtAAFQZ5BHdyk943.png

可以看到,雖然會出現異常,但我們使用recover()捕獲之后,就不會出現系統崩潰退出的情形,而只是將該方法結束。其中fmt.Printf("%d / %d = %dn", i, j, k)語句并沒有執行到,因為代碼執行到他的上一步已經出現異常導致該方法提前結束。
4 recover

當有可以預見的錯誤時,又不希望程序崩潰退出,可以使用recover()語句來捕獲未處理的panic。recover應當放在defer語句中,且該語句應該在方法中前部,避免未能執行到defer語句時就引發了系統異常退出。

package main

import (
    "fmt"
)

func divide() {
    //通過defer,確保該方法只要執行完畢都要執行該匿名方法
    defer func() {
        //進行異常捕獲
        if err := recover(); err != nil {
            fmt.Printf("Runtime panic caught: %vn", err)
        }
    }()

    var i = 1
    var j = 0
    k := i / j
    fmt.Printf("%d / %d = %dn", i, j, k)
}

func main() {
    divide()
    fmt.Println("divide 方法調用完畢,回到 main 函數")
}

可以看到,雖然會出現異常,但我們使用recover()捕獲之后,就不會出現系統崩潰退出的情形,而只是將該方法結束。其中fmt.Printf("%d / %d = %dn", i, j, k)語句并沒有執行到,因為代碼執行到他的上一步已經出現異常導致該方法提前結束。

五、總結

通過以上的學習,大家可以以使用為目的的初步了解到go的基礎語法,但是僅憑本文想要學明白go是完全不夠的。例如go的最大優勢之一“協程”,由于文章目的就沒有特別詳細展開,有興趣的同學可以繼續學習。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2967

    瀏覽量

    104749
  • Go
    Go
    +關注

    關注

    0

    文章

    43

    瀏覽量

    12253
收藏 人收藏

    評論

    相關推薦

    快充技術&芯片詳解 十分鐘讓你的手機滿血復活

    快沖技術全面來襲!你了解市面上的這些手機用的快充技術原理嗎?你知道有哪些電池管理芯片的使用讓你的手機十分鐘滿血復活嗎?今天跟小編一起,了解一下這些快充技術和芯片吧。
    發表于 06-23 13:35 ?6.6w次閱讀

    十分鐘學會Xilinx FPGA 設計1.1

    十分鐘學會Xilinx FPGA 設計1.1
    發表于 08-10 11:10

    ModelSim SE 十分鐘入門

    ModelSim SE 十分鐘入門[table=98%][tr][td][table=98%][tr][td]1.ModuleSim SE 快速入門本文以ModelSim SE 5.6版本為
    發表于 08-12 15:07

    ModelSim SE 十分鐘入門

    ModelSim SE 十分鐘入門
    發表于 08-20 20:33

    十分鐘學會ISE

    十分鐘學會ISE
    發表于 03-26 09:39

    十分鐘學會ISE

    十分鐘學會ISE
    發表于 09-05 22:49

    全球首發十分鐘快速充滿電移動電源

    `快速充電無壓力:十分鐘能充滿的移動電源MY POWER 任性系列土豪金版深圳市麥可電源有限公司是一家專業從事高頻開關電源研發、生產、銷售、服務于一體的綜合性企業。產品廣泛應用于網絡系統、安防系統
    發表于 03-25 14:56

    采集系統需要隔十分鐘采集10S數據,怎么實現?

    畢業實驗需要用labview做個采集界面,但是我沒有這方面基礎,所以這個隔十分鐘采集10S數據功能怎么也實現不了,現在我就做到下面這樣,求大神指導一二~不勝感激!
    發表于 01-13 12:56

    BearPi-HM Nano 十分鐘上手教程資料

    BearPi-HM Nano 十分鐘上手教程一、準備工作二、開始下載三、開始部署環境
    發表于 04-13 10:20

    基于STM32F103RB的數碼管如何去實現十分鐘計時呢

    基于STM32F103RB的數碼管如何去實現十分鐘計時呢?其中斷代碼是怎樣的?
    發表于 11-17 06:12

    遇到SE5經常自動重啟,大約十幾分鐘到二十分鐘左右重啟一次的問題如何解決?

    遇到SE5經常自動重啟,大約十幾分鐘到二十分鐘左右重啟一次的問題怎么辦
    發表于 09-18 08:13

    十分鐘學會Xilinx FPGA 設計

    十分鐘學會Xilinx FPGA 設計 Xilinx FPGA設計基礎系統地介紹了Xilinx公司FPGA的結構特點和相關開發軟件的使用方法,詳細描述了VHDL語言的語法和設計方法,并深入討
    發表于 03-15 15:09 ?178次下載

    三星改革智能手機充電技術,充滿只需十分鐘

    現在的手機電池續航短的問題一直手機領域研究的重點。近日,三星爆出猛料,宣布已經成功研制出石墨烯電池,以后充電只需要十分鐘
    發表于 12-02 11:24 ?2085次閱讀

    英國搭建太陽能汽車充電網試點項目,電動汽車在三十分鐘內完成充電

    英國計劃在國內設立100多座以太陽能為能源的汽車充電站。每個充電站場地配備24個汽車充電區,車主可用手機app預訂充電。據悉,所有電動汽車均能在三十分鐘內完成充電,部分車型甚至在十分鐘內即可充滿。
    的頭像 發表于 04-06 17:28 ?3235次閱讀

    十分鐘分析穩壓三極管工作原理資料下載

    電子發燒友網為你提供十分鐘分析穩壓三極管工作原理資料下載的電子資料下載,更有其他相關的電路圖、源代碼、課件教程、中文資料、英文資料、參考設計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發表于 04-11 08:54 ?3次下載
    <b class='flag-5'>十分鐘</b>分析穩壓三極管工作原理資料下載
    主站蜘蛛池模板: 又粗又爽又色男女乱淫播放男女| 天天干b| 免费大片av手机看片| 西西人体44renti大胆亚洲| 国产精品丝袜在线观看| 全部免费a级毛片| 99国产精品农村一级毛片| 高清在线观看视频| 亚洲淫视频| 国产做a爰片久久毛片| 九色综合网| 亚洲小视频在线播放| 黄色片免费看视频| 久艹精品| 亚洲成人综合在线| 国产大乳孕妇喷奶水在线观看| 狠狠干综合| 正在播放久久| 韩国免费三片在线视频| 丁香色综合| 天天摸天天做天天爽水多| www.毛片网站| 一区二区三区亚洲| 欧美国产一区二区二区| 奇米影视99| 亚洲色图综合| xx在线观看| 中文字幕一二三区乱码老| 欧美特黄视频在线观看| 欧美午夜一区| 香港澳门a级三级三级全黄| 最刺激黄a大片免费观看| 亚洲福利秒拍一区二区| 美日韩中文字幕| 国产逼逼视频| 色多多免费在线观看| 色综合久久98天天综合| 一级aa 毛片高清免费看| dy天堂| 国产在线精品一区免费香蕉| 国产一区二区在线不卡|