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

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

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

3天內不再提示

仿Flow構建器創建數據流教程

jf_78858299 ? 來源:北洋洋洋 ? 作者:北洋 ? 2023-02-14 15:31 ? 次閱讀

第一步

首先回顧下前面的知識點:

flow提供的只是一個 「擴展函數」 返回的是一個保存了這個方法的類實例,并且該類提供emit方法以供flow中調用

構建Flow

「flow方法」

object Flow {
    fun  flow(collect: Collector<T>.() -> Unit): SafeFlowCollector {
        return SafeFlowCollector(collect)
    }
}

定義一個Flow類,內部提供flow方法。

「SafeCollector」 類:

class SafeFlowCollector<T>(val collect: Collector.() -> Unit) {
    //將該Function保存在調用flow后創建的實例中獲取實例創建FlowCollector
    fun collectFunction(a: (T) -> Unit) {
        val co = Collector(a)
        co.collect()
    }

「Collector類」

class Collector<T>(val action: (a: T) -> Unit) {
    fun emit(value: T) {
        action(value)
    }
}

這是flow方法需要創建的三個類,雖然功能不多,但是對于簡單的構建流還是綽綽有余的。

分析

可以看到flow方法傳入的方法參數collect被定義為了Collector的擴展函數,并且保存在了剛創建的SafeCollector的類中用collect函數表示。

「第一個功能」 :flow參數提交的類型和collect中收到的類型一致,我采用了更加直接的形式定義flow時需要設置傳輸的類型,在emit和collect中都是對應的類型。

「實現」

flow定義類型和emit類型保持一致:通過Collector< T >實現

flow定義類型和收集到的類型一致:通過SafeFlowCollector< T >實現

第二步

構建collect收集器

第一步發射器設置好后,我們限制了發送的類型和接受的類型,并且將發送邏輯保存在了實例中。接下來我們需要調用該實例對象以觸發發送邏輯,在發送邏輯中還需要調用到我們收集的邏輯。

因此收集邏輯需要單獨存放,因此需要單獨構建一個類,這個類還必須可以調用到發送邏輯。

?注:Flow中采用的是collect收集觸發flow流發送邏輯,本人使用時是按照collectFunction定義的。兩者邏輯一樣只是名稱不同

?

flow要構造成哪個類的構造函數,該類就需要持有collect傳入的方法。這也是Collector的功能

SafeFlowCollector和Collector

Collector保存collect傳入的方法,flow擴展Collector以使他可以觸發發射邏輯也就是flow傳入的參數。

class SafeFlowCollector<T>(val collect: Collector.() -> Unit)  //擴展函數

//發送邏輯emit,這個action是從哪里來的呢?
class Collector<T>(val action: (a: T) -> Unit) {
    fun emit(value: T) {
        action(value)
    }
}

再解collectFunction方法:

上面說到action方法,接著看:

fun collectFunction(a: (T) -> Unit) {
    //可以看到調用collectFunction方法將傳入的方法參數保存到了Collector中也就是action方法
    val co = Collector(a)
    //觸發collect,collect也就是flow中傳入的方法。
    co.collect()
}

原生flow,collect的demo:

?注:將上述三個類拷貝到您的項目中即可調用

?

Flow.flow {
    Log.i(TAG, "emit before")
    emit("1")
    Log.i(TAG, "emit after")
}.collectFunction {
    Log.i(TAG, "collectionFunction is : $it")
}

總結

因此可以看到調用collectFunction方法會調用到flow傳入的方法中,在flow傳入的方法中調用emit又會執行collectFunction傳入的方法。

?ps:collectFunction類比于原生Flow中的collect方法即可

?

擴展中間轉換符

flow和collect我們支持了,現在我們來擴展轉換操作符。這里還是簡單實現,原生Flow的實現看的很繞。

map操作符

map方法接受的是一個方法。并且該方法的參數是原數據,經過轉換后返回的值是collect接受的值。

首先我們需要確定幾個點:

1、map的參數如何確定?

?map的參數即上一個Flow emit的值,而在我們這個里面emit的值是通過flow< T >指定的,所以參數直接寫T就可以。2.map的返回值如何確定?

?

?map的返回值要經過兩個階段,收到上一個flow發送的值調用轉換函數把值傳入得到結果,因此map中最后一行即為返回值。

?

3.支持鏈式調用map

?map之后還需要再次經歷map或者collectFunction方法,因此他返回的也必須是一個flowSafeCollector。參數是map傳入方法的返回值。

?

確定好這些來實現,由于需要調用到上一個flow的collect方法, 「原生中是擴展函數this即代表上一個Flow。本demo異曲同工,直接定義為該類的函數」 。于是實現如下, 「修改SafeFlowCollector」 類即可:

class SafeFlowCollector<T>(val collect: Collector.() -> Unit) {
    fun collectFunction(a: (T) -> Unit) {
        val co = Collector(a)
        co.collect()
    }

    //對比發現只是擴展了這個map方法
    fun  map(mapFunction: (T) -> R): SafeFlowCollector {
                //外層調用經map轉換后的collectionFunction會走到flow里面
        return Flow.flow {
                //this@SafeFlowCollector是為了保證調用到調用map函數的flow觸發這個flow的收集
                this@SafeFlowCollector.collectFunction {
                    //當最內層flow函數調用emit,此collectFunction會收到回調,進行轉換后調用flow返回給最外層的collectFunction方法。
                    emit(mapFunction(it))
                }
        }
    }

}

讀者可以直接將上面的SafeFlowCollector換成這個即可。

可支持map轉換Flow的demo

Flow.flow {
    emit("2")
}.map {
    it.toInt()
}.map {
    it.toString()
}.collectFunction {
    Log.i(TAG, "onCreate: it   $it")
}

「最后還是放出這張圖片:」

圖片

1649984327(1).png

擴展中間操作符

還是像map一樣,直接把該方法添加到 「SafeFlowCollector」 類中即可

//新增擴展zip操作流,用于多個流發射,就近原則誰先返回用誰
//tips1:收集器類型及·返回流類型,由于返回值相同。因此復用調用方流的泛型即可
//2:開啟收集后觸發多個流的收集,利用標志位進行判斷是否發射。目前采用這種方式。缺點:流發射后應該關閉但是此處只是限制了流的發射邏輯
fun zip(twoFlow: SafeFlowCollector<T>): SafeFlowCollector {
    return Flow.flow {
        var a = false //通過定義condition判斷,不支持協程需要手動切換線程測試效果
        //開啟兩個劉的收集,誰先收集到誰先返回
        this@SafeFlowCollector.collectFunction {
            if (!a) {
                a = true
                this.emit(it)
            }
        }
        twoFlow.collectFunction {
            if (!a) {
                a = true
                this.emit(it)
            }
        }
    }
}

?該種方案可支持多個Flow發射,zip中將參數變為可變參數即可。SafeCollector中擴展

?

zip操作符Demo

val flow1 = Flow.flow<Int> {
        emit(2)
}
Flow.flow<String> {
    Thread{
        emit("111")
    }.interrupt()
}.map {
    it.toInt()
}.zip(flow1).collectFunction {
    Log.i(TAG, "onCreate: ZIP操作符下的Flow收集器收集到的數據位 $it")
}

?上述方案采用標志位實現不太優雅,有更好的方式可以提出~~

?

「不支持協程~~~,需要調度手動切換線程」

總結

「轉換操作符只是中間操作符的一種,其他中間操作符原理大致都一樣。都是經過在封裝一次flow然后觸發上級flow的收集,最后調用到最里層的flow,調用emit在一層層經過中間操作符處理給到最外層」

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

    關注

    88

    文章

    3683

    瀏覽量

    94885
  • 函數
    +關注

    關注

    3

    文章

    4371

    瀏覽量

    64230
  • Flow
    +關注

    關注

    0

    文章

    10

    瀏覽量

    8964
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    SSIS體系結構控制數據流技術對比分析

    數據流(Data Flow)是控制中的核心組件,用于把數據提取到服務內存中,轉換數據并把
    發表于 11-06 11:19 ?5002次閱讀

    大眾數據流分析

    、3.0發動機數據流定義與解釋別克君威2.0發動機數據流定義與解釋凱越數據流列表凱越發動機數據流定義賽歐數據流列表賽歐
    發表于 06-15 12:28

    大眾防盜數據流

    汽車防盜數據流
    發表于 08-31 16:23

    研究labview的數據流

    我在NI上下載了labview一個程序,運行起來還有點小問題,我想運行 看看他的數據流,深入的研究下,哪位大神能指導下,怎么增加個仿真信號 和輸出采集,這樣能清楚的看到其整個數據流的過程,謝謝~
    發表于 12-31 10:40

    LabVIEW中的數據流編程基礎

      LabVIEW按照數據流(dataflow)模式運行VI。 當接受到所有所需的輸入時,程序框圖節點將運行。節點在運行時產生輸出端數據并將該數據傳送給數據流路徑中的下一個節點。
    發表于 11-20 10:47

    關于高速數據流盤處理技術看完你就懂了

    本文討論了支持高速數據流處理的技術、最大化系統處理性能的應用設計和在數據流導入磁盤與數據流導入存儲應用中可獲得的
    發表于 04-29 06:25

    基于數據流的Java字節碼分析

    本文基于數據流框架理論,提出了如何將數據流分析方法應用于JAVA 字節碼中,通過建立數據流與半格、數據流和函數調用圖的關系,從而對類型信息進行分析。實驗表明該
    發表于 12-25 13:22 ?9次下載

    網絡數據流存儲算法分析與實現

    針對網絡數據流存儲的瓶頸問題,提出了一種網絡數據流存儲算法分析與實現方法,仿真結果表明,模型能顯著提高網絡數據流的實時存儲能力
    發表于 05-26 15:57 ?21次下載
    網絡<b class='flag-5'>數據流</b>存儲算法分析與實現

    基于數據流特征的電子文件訪問方法

    的概念,提取了常用網絡協議傳輸電子文件的特征值,設計和構建了擴展性強的數據流特征數據庫,并給出了該特征數據庫檢測和防止電子文件網絡泄漏過程。實驗數據
    發表于 11-15 14:15 ?5次下載

    基于FPGA芯片的數據流結構分析

    Virtex 型FPGA 芯片是Xilinx 公司芯片系列中的一種,Virtex 系列的數據流及配置邏輯與XC4000 的數據流及配置邏輯有顯著不同,但卻與Xilinx 的FPGA 家族保持了很大
    發表于 11-18 11:37 ?2621次閱讀

    數據流編程模型優化

    數據流編程模型將程序的計算與通信分離,暴露了應用程序潛在的并行性并簡化了編程難度。分布式計算框架利用廉價PC構建多核集群解決了大規模并行計算問題,但多核集群層次性存儲結構和處理單元對數據流程序的性能
    發表于 11-23 15:48 ?3次下載
    <b class='flag-5'>數據流</b>編程模型優化

    基于角度方差的數據流異常檢測算法

    傳統基于歐氏距離的異常檢測算法在高維數據檢測中存在精度無法保證以及運行時間過長的問題。為此,結合高維數據流的特點運用角度方差的方法,提出一種改進的基于角度方差的數據流異常檢測算法。通過構建
    發表于 01-17 11:29 ?1次下載
    基于角度方差的<b class='flag-5'>數據流</b>異常檢測算法

    數據流是什么

    數據流最初是通信領域使用的概念,代表傳輸中所使用的信息的數字編碼信號序列。然而,我們所提到的數據流概念與此不同。這個概念最初在1998年由Henzinger在文獻87中提出,他將數據流定義為“只能以事先規定好的順序被讀取一次的
    的頭像 發表于 02-27 15:25 ?7373次閱讀

    Labview數據流編程的簡單介紹

    Labview數據流編程基本概念視頻教學
    的頭像 發表于 08-05 06:05 ?4329次閱讀

    控制數據流的區別

    控制數據流的區別? 在計算機科學中,控制數據流是兩個非常重要的概念。雖然它們經常一起使用,但它們具有非常不同的含義。本文將討論控制
    的頭像 發表于 09-13 11:17 ?6933次閱讀
    主站蜘蛛池模板: 亚洲欧美国产视频 | 亚色综合| 欧美性aaa| 精品黄色录像 | 免费永久欧美性色xo影院 | 在线免费你懂的 | 日黄网站 | 亚洲 欧美 自拍 另类 | 亚洲天堂一区二区三区 | 欧美成人影院免费观 | 午夜欧美精品久久久久久久久 | 亚洲网站免费 | 一级做a爰片久久毛片一 | 天天添天天操 | 欧美极品在线播放 | 久久刺激视频 | 美女被视频网站在线看九色 | 色噜噜狠狠色综合欧洲 | 婷婷综合久久狠狠色99h | 在线观看h视频 | 午夜色片| 新版天堂中文资源8在线 | 国产黄色三级网站 | 亚洲国产精品第一页 | 日本黄色小视频网站 | 三级黄色在线 | brazzersvideosexhd欧美高清 | 天天干视频网站 | 明日花在线观看 | 黄网站观看 | 欧美性操| 欧美成人性色 | 四虎精品影院在线观看视频 | bt天堂资源在线种子 | 99精品热视频 | 男人天堂网2021 | 久久久久国产免费 | 5月色婷婷 | 黄a在线| 三级视频网 | 国产精品午夜免费观看网站 |