国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】83 | 開(kāi)源實(shí)戰(zhàn)三(下):借Google Guava學(xué)習(xí)三大編程范式中的函數(shù)式編程

這篇具有很好參考價(jià)值的文章主要介紹了【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】83 | 開(kāi)源實(shí)戰(zhàn)三(下):借Google Guava學(xué)習(xí)三大編程范式中的函數(shù)式編程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

現(xiàn)在主流的編程范式主要有三種,面向過(guò)程、面向?qū)ο蠛秃瘮?shù)式編程。在理論部分,我們已經(jīng)詳細(xì)講過(guò)前兩種了。今天,我們?cè)俳铏C(jī)會(huì)講講剩下的一種,函數(shù)式編程。
函數(shù)式編程并非一個(gè)很新的東西,早在 50 多年前就已經(jīng)出現(xiàn)了。近幾年,函數(shù)式編程越來(lái)越被人關(guān)注,出現(xiàn)了很多新的函數(shù)式編程語(yǔ)言,比如 Clojure、Scala、Erlang 等。一些非函數(shù)式編程語(yǔ)言也加入了很多特性、語(yǔ)法、類(lèi)庫(kù)來(lái)支持函數(shù)式編程,比如 Java、Python、Ruby、JavaScript 等。除此之外,Google Guava 也有對(duì)函數(shù)式編程的增強(qiáng)功能。

函數(shù)式編程因其編程的特殊性,僅在科學(xué)計(jì)算、數(shù)據(jù)處理、統(tǒng)計(jì)分析等領(lǐng)域,才能更好地發(fā)揮它的優(yōu)勢(shì),所以,我個(gè)人覺(jué)得,它并不能完全替代更加通用的面向?qū)ο缶幊谭妒?。但是,作為一種補(bǔ)充,它也有很大存在、發(fā)展和學(xué)習(xí)的意義。所以,我覺(jué)得有必要在專(zhuān)欄里帶你一塊學(xué)習(xí)一下。
話不多說(shuō),讓我們正式開(kāi)始今天的學(xué)習(xí)吧!

到底什么是函數(shù)式編程?

函數(shù)式編程的英文翻譯是 Functional Programming。 那到底什么是函數(shù)式編程呢?
在前面的章節(jié)中,我們講到,面向過(guò)程、面向?qū)ο缶幊滩](méi)有嚴(yán)格的官方定義。在當(dāng)時(shí)的講解中,我也只是給出了我自己總結(jié)的定義。而且,當(dāng)時(shí)給出的定義也只是對(duì)兩個(gè)范式主要特性的總結(jié),并不是很?chē)?yán)格。實(shí)際上,函數(shù)式編程也是如此,也沒(méi)有一個(gè)嚴(yán)格的官方定義。所以,接下來(lái),我就從特性上來(lái)告訴你,什么是函數(shù)式編程。

嚴(yán)格上來(lái)講,函數(shù)式編程中的“函數(shù)”,并不是指我們編程語(yǔ)言中的“函數(shù)”概念,而是指數(shù)學(xué)“函數(shù)”或者“表達(dá)式”(比如,y=f(x))。不過(guò),在編程實(shí)現(xiàn)的時(shí)候,對(duì)于數(shù)學(xué)“函數(shù)”或“表達(dá)式”,我們一般習(xí)慣性地將它們?cè)O(shè)計(jì)成函數(shù)。所以,如果不深究的話,函數(shù)式編程中的“函數(shù)”也可以理解為編程語(yǔ)言中的“函數(shù)”。
每個(gè)編程范式都有自己獨(dú)特的地方,這就是它們會(huì)被抽象出來(lái)作為一種范式的原因。面向?qū)ο缶幊套畲蟮奶攸c(diǎn)是:以類(lèi)、對(duì)象作為組織代碼的單元以及它的四大特性。面向過(guò)程編程最大的特點(diǎn)是:以函數(shù)作為組織代碼的單元,數(shù)據(jù)與方法相分離。那函數(shù)式編程最獨(dú)特的地方又在哪里呢?

實(shí)際上,函數(shù)式編程最獨(dú)特的地方在于它的編程思想。函數(shù)式編程認(rèn)為,程序可以用一系列數(shù)學(xué)函數(shù)或表達(dá)式的組合來(lái)表示。函數(shù)式編程是程序面向數(shù)學(xué)的更底層的抽象,將計(jì)算過(guò)程描述為表達(dá)式。不過(guò),這樣說(shuō)你肯定會(huì)有疑問(wèn),真的可以把任何程序都表示成一組數(shù)學(xué)表達(dá)式嗎?

理論上講是可以的。但是,并不是所有的程序都適合這么做。函數(shù)式編程有它自己適合的應(yīng)用場(chǎng)景,比如開(kāi)篇提到的科學(xué)計(jì)算、數(shù)據(jù)處理、統(tǒng)計(jì)分析等。在這些領(lǐng)域,程序往往比較容易用數(shù)學(xué)表達(dá)式來(lái)表示,比起非函數(shù)式編程,實(shí)現(xiàn)同樣的功能,函數(shù)式編程可以用很少的代碼就能搞定。但是,對(duì)于強(qiáng)業(yè)務(wù)相關(guān)的大型業(yè)務(wù)系統(tǒng)開(kāi)發(fā)來(lái)說(shuō),費(fèi)勁吧啦地將它抽象成數(shù)學(xué)表達(dá)式,硬要用函數(shù)式編程來(lái)實(shí)現(xiàn),顯然是自討苦吃。相反,在這種應(yīng)用場(chǎng)景下,面向?qū)ο缶幊谈雍线m,寫(xiě)出來(lái)的代碼更加可讀、可維護(hù)。

剛剛講的是函數(shù)式編程的編程思想,如果我們?cè)倬唧w到編程實(shí)現(xiàn),函數(shù)式編程跟面向過(guò)程編程一樣,也是以函數(shù)作為組織代碼的單元。不過(guò),它跟面向過(guò)程編程的區(qū)別在于,它的函數(shù)是無(wú)狀態(tài)的。何為無(wú)狀態(tài)?簡(jiǎn)單點(diǎn)講就是,函數(shù)內(nèi)部涉及的變量都是局部變量,不會(huì)像面向?qū)ο缶幊棠菢樱蚕眍?lèi)成員變量,也不會(huì)像面向過(guò)程編程那樣,共享全局變量。函數(shù)的執(zhí)行結(jié)果只與入?yún)⒂嘘P(guān),跟其他任何外部變量無(wú)關(guān)。同樣的入?yún)?,不管怎么?zhí)行,得到的結(jié)果都是一樣的。這實(shí)際上就是數(shù)學(xué)函數(shù)或數(shù)學(xué)表達(dá)式的基本要求。我舉個(gè)例子來(lái)簡(jiǎn)單解釋一下。

// 有狀態(tài)函數(shù): 執(zhí)行結(jié)果依賴b的值是多少,即便入?yún)⑾嗤?,多次?zhí)行函數(shù),函數(shù)的返回值有可能不同,因?yàn)閎值有可能不同。
int b;
int increase(int a) {
  return a + b;
}
// 無(wú)狀態(tài)函數(shù):執(zhí)行結(jié)果不依賴任何外部變量值,只要入?yún)⑾嗤?,不管?zhí)行多少次,函數(shù)的返回值就相同
int increase(int a, int b) {
  return a + b;
}

這里稍微總結(jié)一下,不同的編程范式之間并不是截然不同的,總是有一些相同的編程規(guī)則。比如,不管是面向過(guò)程、面向?qū)ο筮€是函數(shù)式編程,它們都有變量、函數(shù)的概念,最頂層都要有 main 函數(shù)執(zhí)行入口,來(lái)組裝編程單元(類(lèi)、函數(shù)等)。只不過(guò),面向?qū)ο蟮木幊虇卧穷?lèi)或?qū)ο螅嫦蜻^(guò)程的編程單元是函數(shù),函數(shù)式編程的編程單元是無(wú)狀態(tài)函數(shù)。

Java 對(duì)函數(shù)式編程的支持

我們前面講到,實(shí)現(xiàn)面向?qū)ο缶幊滩灰欢ǚ堑檬褂妹嫦驅(qū)ο缶幊陶Z(yǔ)言,同理,實(shí)現(xiàn)函數(shù)式編程也不一定非得使用函數(shù)式編程語(yǔ)言?,F(xiàn)在,很多面向?qū)ο缶幊陶Z(yǔ)言,也提供了相應(yīng)的語(yǔ)法、類(lèi)庫(kù)來(lái)支持函數(shù)式編程。
接下來(lái),我們就看下 Java 這種面向?qū)ο缶幊陶Z(yǔ)言,對(duì)函數(shù)式編程的支持,借機(jī)加深一下你對(duì)函數(shù)式編程的理解。我們先來(lái)看下面這樣一段非常典型的 Java 函數(shù)式編程的代碼。

public class FPDemo {
  public static void main(String[] args) {
    Optional<Integer> result = Stream.of("f", "ba", "hello")
            .map(s -> s.length())
            .filter(l -> l <= 3)
            .max((o1, o2) -> o1-o2);
    System.out.println(result.get()); // 輸出2
  }
}

這段代碼的作用是從一組字符串?dāng)?shù)組中,過(guò)濾出長(zhǎng)度小于等于 3 的字符串,并且求得這其中的最大長(zhǎng)度。
如果你不了解 Java 函數(shù)式編程的語(yǔ)法,看了上面的代碼或許會(huì)有些懵,主要的原因是,Java 為函數(shù)式編程引入了三個(gè)新的語(yǔ)法概念:Stream 類(lèi)、Lambda 表達(dá)式和函數(shù)接口(Functional Inteface)。Stream 類(lèi)用來(lái)支持通過(guò)“.”級(jí)聯(lián)多個(gè)函數(shù)操作的代碼編寫(xiě)方式;引入 Lambda 表達(dá)式的作用是簡(jiǎn)化代碼編寫(xiě);函數(shù)接口的作用是讓我們可以把函數(shù)包裹成函數(shù)接口,來(lái)實(shí)現(xiàn)把函數(shù)當(dāng)做參數(shù)一樣來(lái)使用(Java 不像 C 一樣支持函數(shù)指針,可以把函數(shù)直接當(dāng)參數(shù)來(lái)使用)。

首先,我們來(lái)看下 Stream 類(lèi)。

假設(shè)我們要計(jì)算這樣一個(gè)表達(dá)式:(3-1)*2+5。如果按照普通的函數(shù)調(diào)用的方式寫(xiě)出來(lái),就是下面這個(gè)樣子:

add(multiply(subtract(3,1),2),5);

不過(guò),這樣編寫(xiě)代碼看起來(lái)會(huì)比較難理解,我們換個(gè)更易讀的寫(xiě)法,如下所示:

subtract(3,1).multiply(2).add(5);

我們知道,在 Java 中,“.”表示調(diào)用某個(gè)對(duì)象的方法。為了支持上面這種級(jí)聯(lián)調(diào)用方式,我們讓每個(gè)函數(shù)都返回一個(gè)通用的類(lèi)型:Stream 類(lèi)對(duì)象。在 Stream 類(lèi)上的操作有兩種:中間操作和終止操作。中間操作返回的仍然是 Stream 類(lèi)對(duì)象,而終止操作返回的是確定的值結(jié)果。

我們?cè)賮?lái)看之前的例子。我對(duì)代碼做了注釋解釋?zhuān)缦滤?。其中,map、filter 是中間操作,返回 Stream 類(lèi)對(duì)象,可以繼續(xù)級(jí)聯(lián)其他操作;max 是終止操作,返回的不是 Stream 類(lèi)對(duì)象,無(wú)法再繼續(xù)往下級(jí)聯(lián)處理了。

public class FPDemo {
  public static void main(String[] args) {
    Optional<Integer> result = Stream.of("f", "ba", "hello") // of返回Stream<String>對(duì)象
            .map(s -> s.length()) // map返回Stream<Integer>對(duì)象
            .filter(l -> l <= 3) // filter返回Stream<Integer>對(duì)象
            .max((o1, o2) -> o1-o2); // max終止操作:返回Optional<Integer>
    System.out.println(result.get()); // 輸出2
  }
}

其次,我們?cè)賮?lái)看下 Lambda 表達(dá)式。
我們前面講到,Java 引入 Lambda 表達(dá)式的主要作用是簡(jiǎn)化代碼編寫(xiě)。實(shí)際上,我們也可以不用 Lambda 表達(dá)式來(lái)書(shū)寫(xiě)例子中的代碼。我們拿其中的 map 函數(shù)來(lái)舉例說(shuō)明一下。

下面有三段代碼,第一段代碼展示了 map 函數(shù)的定義,實(shí)際上,map 函數(shù)接收的參數(shù)是一個(gè) Function 接口,也就是待會(huì)兒要講到的函數(shù)接口。第二段代碼展示了 map 函數(shù)的使用方式。第三段代碼是針對(duì)第二段代碼用 Lambda 表達(dá)式簡(jiǎn)化之后的寫(xiě)法。實(shí)際上,Lambda 表達(dá)式在 Java 中只是一個(gè)語(yǔ)法糖而已,底層是基于函數(shù)接口來(lái)實(shí)現(xiàn)的,也就是第二段代碼展示的寫(xiě)法。

// Stream中map函數(shù)的定義:
public interface Stream<T> extends BaseStream<T, Stream<T>> {
  <R> Stream<R> map(Function<? super T, ? extends R> mapper);
  //...省略其他函數(shù)...
}
// Stream中map的使用方法:
Stream.of("fo", "bar", "hello").map(new Function<String, Integer>() {
  @Override
  public Integer apply(String s) {
    return s.length();
  }
});
// 用Lambda表達(dá)式簡(jiǎn)化后的寫(xiě)法:
Stream.of("fo", "bar", "hello").map(s -> s.length());

Lambda 表達(dá)式語(yǔ)法不是我們學(xué)習(xí)的重點(diǎn)。我這里只稍微介紹一下。如果感興趣,你可以自行深入研究。
Lambda 表達(dá)式包括三部分:輸入、函數(shù)體、輸出。表示出來(lái)的話就是下面這個(gè)樣子:

(a, b) -> { 語(yǔ)句1; 語(yǔ)句2;...; return 輸出; } //a,b是輸入?yún)?shù)

實(shí)際上,Lambda 表達(dá)式的寫(xiě)法非常靈活。我們剛剛給出的是標(biāo)準(zhǔn)寫(xiě)法,還有很多簡(jiǎn)化寫(xiě)法。比如,如果輸入?yún)?shù)只有一個(gè),可以省略 (),直接寫(xiě)成 a->{…};如果沒(méi)有入?yún)ⅲ梢灾苯訉⑤斎牒图^都省略掉,只保留函數(shù)體;如果函數(shù)體只有一個(gè)語(yǔ)句,那可以將{}省略掉;如果函數(shù)沒(méi)有返回值,return 語(yǔ)句就可以不用寫(xiě)了。
如果我們把之前例子中的 Lambda 表達(dá)式,全部替換為函數(shù)接口的實(shí)現(xiàn)方式,就是下面這樣子的。代碼是不是多了很多?

Optional<Integer> result = Stream.of("f", "ba", "hello")
        .map(s -> s.length())
        .filter(l -> l <= 3)
        .max((o1, o2) -> o1-o2);
        
// 還原為函數(shù)接口的實(shí)現(xiàn)方式
Optional<Integer> result2 = Stream.of("fo", "bar", "hello")
        .map(new Function<String, Integer>() {
          @Override
          public Integer apply(String s) {
            return s.length();
          }
        })
        .filter(new Predicate<Integer>() {
          @Override
          public boolean test(Integer l) {
            return l <= 3;
          }
        })
        .max(new Comparator<Integer>() {
          @Override
          public int compare(Integer o1, Integer o2) {
            return o1 - o2;
          }
        });

最后,我們來(lái)看下函數(shù)接口。

實(shí)際上,上面一段代碼中的 Function、Predicate、Comparator 都是函數(shù)接口。我們知道,C 語(yǔ)言支持函數(shù)指針,它可以把函數(shù)直接當(dāng)變量來(lái)使用。但是,Java 沒(méi)有函數(shù)指針這樣的語(yǔ)法。所以,它通過(guò)函數(shù)接口,將函數(shù)包裹在接口中,當(dāng)作變量來(lái)使用。

實(shí)際上,函數(shù)接口就是接口。不過(guò),它也有自己特別的地方,那就是要求只包含一個(gè)未實(shí)現(xiàn)的方法。因?yàn)橹挥羞@樣,Lambda 表達(dá)式才能明確知道匹配的是哪個(gè)接口。如果有兩個(gè)未實(shí)現(xiàn)的方法,并且接口入?yún)ⅰ⒎祷刂刀家粯?,?Java 在翻譯 Lambda 表達(dá)式的時(shí)候,就不知道表達(dá)式對(duì)應(yīng)哪個(gè)方法了。
我把 Java 提供的 Function、Predicate 這兩個(gè)函數(shù)接口的源碼,摘抄過(guò)來(lái)貼到了下面,你可以對(duì)照著它們,理解我剛剛對(duì)函數(shù)接口的講解。

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);  // 只有這一個(gè)未實(shí)現(xiàn)的方法
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t); // 只有這一個(gè)未實(shí)現(xiàn)的方法
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

以上講的就是 Java 對(duì)函數(shù)式編程的語(yǔ)法支持,我想,最開(kāi)始給到的那個(gè)函數(shù)式編程的例子,現(xiàn)在你應(yīng)該能輕松看懂了吧?

Guava 對(duì)函數(shù)式編程的增強(qiáng)

如果你是 Google Guava 的設(shè)計(jì)者,對(duì)于 Java 函數(shù)式編程,Google Guava 還能做些什么呢?
顛覆式創(chuàng)新是很難的。不過(guò)我們可以進(jìn)行一些補(bǔ)充,一方面,可以增加 Stream 類(lèi)上的操作(類(lèi)似 map、filter、max 這樣的終止操作和中間操作),另一方面,也可以增加更多的函數(shù)接口(類(lèi)似 Function、Predicate 這樣的函數(shù)接口)。實(shí)際上,我們還可以設(shè)計(jì)一些類(lèi)似 Stream 類(lèi)的新的支持級(jí)聯(lián)操作的類(lèi)。這樣,使用 Java 配合 Guava 進(jìn)行函數(shù)式編程會(huì)更加方便。
但是,跟我們預(yù)期的相反,Google Guava 并沒(méi)有提供太多函數(shù)式編程的支持,僅僅封裝了幾個(gè)遍歷集合操作的接口,代碼如下所示:

Iterables.transform(Iterable, Function);
Iterators.transform(Iterator, Function);
Collections.transfrom(Collection, Function);
Lists.transform(List, Function);
Maps.transformValues(Map, Function);
Multimaps.transformValues(Mltimap, Function);
...
Iterables.filter(Iterable, Predicate);
Iterators.filter(Iterator, Predicate);
Collections2.filter(Collection, Predicate);
...

從 Google Guava 的 GitHub Wiki 中,我們發(fā)現(xiàn),Google 對(duì)于函數(shù)式編程的使用還是很謹(jǐn)慎的,認(rèn)為過(guò)度地使用函數(shù)式編程,會(huì)導(dǎo)致代碼可讀性變差,強(qiáng)調(diào)不要濫用。這跟我前面對(duì)函數(shù)式編程的觀點(diǎn)是一致的。所以,在函數(shù)式編程方面,Google Guava 并沒(méi)有提供太多的支持。

之所以對(duì)遍歷集合操作做了優(yōu)化,主要是因?yàn)楹瘮?shù)式編程一個(gè)重要的應(yīng)用場(chǎng)景就是遍歷集合。如果不使用函數(shù)式編程,我們只能 for 循環(huán),一個(gè)一個(gè)的處理集合中的數(shù)據(jù)。使用函數(shù)式編程,可以大大簡(jiǎn)化遍歷集合操作的代碼編寫(xiě),一行代碼就能搞定,而且在可讀性方面也沒(méi)有太大損失。

重點(diǎn)回顧

好了,今天的內(nèi)容到此就講完了。我們一塊來(lái)總結(jié)回顧一下,你需要重點(diǎn)掌握的內(nèi)容。
今天,我們講了一下三大編程范式中的最后一個(gè),函數(shù)式編程。盡管越來(lái)越多的編程語(yǔ)言開(kāi)始支持函數(shù)式編程,但我個(gè)人覺(jué)得,它只能是其他編程范式的補(bǔ)充,用在一些特殊的領(lǐng)域發(fā)揮它的特殊作用,沒(méi)法完全替代面向?qū)ο?、面向過(guò)程編程范式。

關(guān)于什么是函數(shù)式編程,實(shí)際上不是很好理解。函數(shù)式編程中的“函數(shù)”,并不是指我們編程語(yǔ)言中的“函數(shù)”概念,而是數(shù)學(xué)中的“函數(shù)”或者“表達(dá)式”概念。函數(shù)式編程認(rèn)為,程序可以用一系列數(shù)學(xué)函數(shù)或表達(dá)式的組合來(lái)表示。
具體到編程實(shí)現(xiàn),函數(shù)式編程以無(wú)狀態(tài)函數(shù)作為組織代碼的單元。函數(shù)的執(zhí)行結(jié)果只與入?yún)⒂嘘P(guān),跟其他任何外部變量無(wú)關(guān)。同樣的入?yún)?,不管怎么?zhí)行,得到的結(jié)果都是一樣。

具體到 Java 語(yǔ)言,它提供了三個(gè)語(yǔ)法機(jī)制來(lái)支持函數(shù)式編程。它們分別是 Stream 類(lèi)、Lambda 表達(dá)式和函數(shù)接口。Google Guava 對(duì)函數(shù)式編程的一個(gè)重要應(yīng)用場(chǎng)景,遍歷集合,做了優(yōu)化,但并沒(méi)有太多的支持,并且我們強(qiáng)調(diào),不要為了節(jié)省代碼行數(shù),濫用函數(shù)式編程,導(dǎo)致代碼可讀性變差。

課堂討論

你可以說(shuō)一說(shuō)函數(shù)式編程的優(yōu)點(diǎn)和缺點(diǎn),以及你對(duì)函數(shù)式編程的看法。你覺(jué)得它能否替代面向?qū)ο缶幊?,成為最主流的編程范式?span toymoban-style="hidden">文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-506531.html

到了這里,關(guān)于【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】83 | 開(kāi)源實(shí)戰(zhàn)三(下):借Google Guava學(xué)習(xí)三大編程范式中的函數(shù)式編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包