主頁 > 後端開發 > Python 為什么要在 18 年前引入布爾型別?且與 C、C++ 和 Java 都不同?

Python 為什么要在 18 年前引入布爾型別?且與 C、C++ 和 Java 都不同?

2020-09-16 12:26:17 後端開發

花下貓語:在上一篇《Python 為什么能支持任意的真值判斷? 》文章中,我們分析了 Python 在真值判斷時的底層實作,可以看出 Python 在對待布林值時,采用了比較寬泛的態度,官方對此是怎么考慮的呢?

下面的文章是我剛翻譯的 PEP-285,作者是 Python 之父 Guido van Rossum,這個 PEP 意義非常重大,Python 的 bool 型別就是從它開始引入的,而我在上篇文章中分析到的很多問題,都能在這篇十幾年前的檔案中找到解釋!另外它還回應了比較典型的一些爭議,值得大家了解下,

PEP原文 : https://www.python.org/dev/peps/pep-0285/

PEP標題: PEP 285 -- Adding a bool type

PEP作者: Guido van Rossum

創建日期: 2002-03-08

合入版本: 2.3

譯者 :豌豆花下貓@Python貓公眾號

PEP翻譯計劃 :https://github.com/chinesehuazhou/peps-cn

概要

本 PEP 提議引入一個新的內置型別bool,它將包含兩個常量FalseTrue,這個 bool 型別是 int 型別的直接子型別(在 C 中),并且在除了 repr() 和 str() 之外的大多數方面,它的值FalseTrue 都將表現得像是 0 和 1(例如,False == 0 和 True == 1 都為真),

所有在概念上需回傳布爾結果的內置操作,都將更改為回傳 False 或 True,而不再是 0 或 1,例如,比較操作、“not”運算和 isinstance() 之類的斷言方法,

評審

我已經收集了太多太多的反饋意見,因此我宣布:評審階段(review period)正式結束, 我今天吃的是中國菜,我的簽語餅上寫著:“Strong and bitter words indicate a weak cause.” 它使我想起了一些反對本 PEP 的帖子... ??

(譯注:1、簽語餅即 fortune cookies,這是一種美國文化特色,美國的中餐館在結賬的時候流行給客人一些寫了簽語的餅干,一般都是祝福語,2、那句簽語出自維克多·雨果,意為:理虧者言辭激烈)

無論如何,這些是我的 BDFL 宣告,(執行摘要(Executive summary):我不會更改任何內容;所有其它提議都會被拒絕,)

1、本 PEP 應該被接受嗎?

=>是的,

有很多反對本 PEP 的觀點,其中多數是出于誤解,我已嘗試在下面的 PEP 正文中澄清一些最常見的誤解,對我而言唯一值得考慮的問題是新手們傾向于寫“ if x == True”,但“if x”就足夠了,下面也有更多關于它的資訊,我認為這不足以拒絕本 PEP,

2、str(True) 應該回傳“True”還是“1”?“1”可能會減少向后兼容性問題,但看起來很奇怪,(repr(True) 將始侄訓傳“True”,)

=>“True”,

幾乎所有評審人都同意這一點,

3、常量應該被命名為“True”和“False”(類似于 None)還是“true”和“false”(像 C++、Java 和 C99 那樣)?

=>True 和 False,

大多數評審人都認為 Python 內的一致性要比跟其它語言的一致性更為重要,

4、是否應該通過適當的告警來消除對布林值的非布爾運算,以便例如 True + 1 最終(在 Python 3000 中)變為非法的?

=>不該

有一小部分觀點響亮的人,希望看到“教科書式”的布爾型別,即完全不支持算術運算,但大多數評審人都同意我,認為布爾型別應該支持算術運算,

**5、operator.truth(x) 應該回傳 int 還是 bool? **

=>bool,

Tim Peters 認為應該回傳一個整數,但是幾乎所有其他評審人都認為應該回傳一個布林值,我的理由:operator.truth() 意味著強制其引數使用布爾型別背景關系(它呼叫 C API PyObject_IsTrue()),無論結果是 int 還是 bool,都是次要的;如果有 bool,則沒有理由不使用它,(在本 PEP 下,operator.truth() 成為了 bool() 的別名;這也可以,)

6、bool 應該繼承自 int 嗎?

=>是的,

在理想的情況下,bool 最好是實作為一種單獨的整數型別,且支持執行混合的算術操作,但是,從 int 繼承出 bool 將極大地簡化實作(部分原因是,所有呼叫PyInt_Check() 的 C 代碼都可兼容——它對于 int 的子類會回傳 true),

另外,我認為這符合可替換性(substitutability)概念:代碼中需要 int 時,可以喂入 bool,它等同于 0 或 1,代碼中需要 bool 時,若賦予 int,則可能不符合預期;例如,3&4 計算為 0,但是當 3 和 4 被視為真值時,卻都為真,

7、是否應該改變“bool”的叫法?

=>不,

一些評審人主張使用 boolean 而不是 bool,因為這樣更容易理解(新手可能聽說過布爾代數(Boolean algebra),但可能對 bool 無感),或者因為他們討厭縮寫,

我的觀點:Python 明智地運用縮寫(例如'def'、'int'、'dict'),我不認為這會造成理解的負擔,對于新手來說,無論它被叫作 waffle 還是 bool 都沒關系;這只是一個新詞,他們很快就能掌握它的含義,

(譯注:waffle,我們一般熟知的意思是“華夫餅干”,但它還有個意思是“無意義的、無關緊要的、胡亂的話”)

一位評審人認為可以叫“truth”,我覺得這個叫法沒有吸引力,實際上更傾向于保留該術語(在檔案中),以指代在 Python 中已經存在的具體的真值概念,例如:“當將一個容器解釋為一個 truth 值時,空容器會被視為假,而非空容器則被視為真”,

8、將來是否應該要求布爾運算子(例如“if”、“and”和“not”)使用一個布林值作為引數,例如令“if []:”變為非法的,要求必須寫成“ if bool([]):” ???

=>不!!!

有些人認為,這就是一門有教科書式布爾型別的語言應該的做法,因為它被提起了,所以其他人擔心我可能會同意這一做法,

我來明確闡述對此的立場:這不是本 PEP 的動機,我也無意進行更改,(另請參見下面的“澄清”部分,)

基本原理

大多數語言最終都會發展出一個布爾型別,甚至 C99(新的改進版 C 標準,尚未廣泛采用)也有一個,(譯注:C99 標準誕生于 1999 年,本 PEP 寫于 2002 年,時過境遷,如今 C99 標準基本上已是落伍的了)

許多程式員都覺得需要一種布爾型別,大多數 Python 檔案因缺少布爾型別而含有歉意,我看過很多模塊,它們在頂部定義了常量“False = 0”和“True = 1”(或類似的常量),并使用它們,

問題是每個人的做法都不一樣,例如,你應該使用“FALSE”、“false”、“False”、“F”還是“f”呢?另外,假值應該為 0 或 None,或是一個其它的布爾型別列印出“true”或“false”呢?在語言中添加一個標準的布爾型別可以解決這些問題,

一些外部庫(例如資料庫和 RPC 相關的包)需要能夠區分布林值和整數值,盡管通常可以制定出解決方案,但如果語言本身提供了標準的布爾型別,則會更容易,這也適用于 Jython:某些 Java 類具有分別用于 int 和 boolean 引數的多載方法或建構式,布爾型別可用于選擇布爾變數,(顯然,某些 COM 介面也是如此,)

標準的布爾型別(bool type)也可以作為強制將值解釋為布林值(Boolean)的方法,該方法可用于標準化布林值,當一個布林值需要歸一化為兩個值之一時,bool(x) 比“not not x”更清晰,也比這種寫法更簡潔:

if x:
    return 1
else:
    return 0

這是從傳授 Python 中得出的一些經驗,當向人們在互動式終端中展示比較運算子時,我認為這有點難看:

>>> a = 13
>>> b = 12
>>> a > b
1
>>>

如果是這樣的話:

>>> a > b
True
>>>

每次會少花一毫秒的時間思考列印出的 0 或 1,

還有一個問題(它甚至困擾了曾經經驗豐富但遠離了 Python 一段時間的人):

>>> cmp(a, b)
1
>>> cmp(a, a)
0
>>>

你可能會傾向于認為 cmp() 也回傳一個布林值,但實際上它可以回傳三個不同的值(-1、0、1),如果整數沒有(通常)被用于表示布林值結果,則這可以更加明顯地表達出其它的含義,(譯注:即只用 True/False 表示布林值,則整數表達其它含義時就不會有歧義)

規范

以下 Python 代碼詳細列舉了新型別的大多數屬性:

class bool(int):

    def __new__(cls, val=0):
        # This constructor always returns an existing instance
        if val:
            return True
        else:
            return False

    def __repr__(self):
        if self:
            return "True"
        else:
            return "False"

    __str__ = __repr__

    def __and__(self, other):
        if isinstance(other, bool):
            return bool(int(self) & int(other))
        else:
            return int.__and__(self, other)

    __rand__ = __and__

    def __or__(self, other):
        if isinstance(other, bool):
            return bool(int(self) | int(other))
        else:
            return int.__or__(self, other)

    __ror__ = __or__

    def __xor__(self, other):
        if isinstance(other, bool):
            return bool(int(self) ^ int(other))
        else:
            return int.__xor__(self, other)

    __rxor__ = __xor__

# Bootstrap truth values through sheer willpower
False = int.__new__(bool, 0)
True = int.__new__(bool, 1)

False 和 True 將是單例的(singletons),像 None 一樣,因為這種型別有兩個值,也許應該將它們稱為“doubletons”?實際的實作將不允許創建 bool 的其它實體,

True 與 False 會被正確地序列化和打包,例如 pickle.loads(pickle.dumps(True)) 將回傳 True, 而marshal.loads(marshal.dumps(True)) 也一樣,

所有在定義上需回傳布爾結果的內置操作,都將更改為回傳 False 或 True,而不再是 0 或 1,

具體而言,這會影響比較操作(<、<=、==、!=、>、>=、is、is not、in、not in),一元運算子'not',內置函式 callable()、hasattr()、isinstance() 和issubclass() ,字典方法 has_key() ,字串和 unicode 方法 endswith()、isalnum()、isalpha()、isdigit()、islower()、isspace()、istitle()、isupper() 和startswith(),unicode方法 isdecimal() 和 isnumeric(),以及檔案物件的“closed”屬性,operator 模塊中的斷言方法也被改為回傳布林值,包括operator.truth(),

由于 bool 繼承自 int,因此 True + 1有效且等于 2,依此類推,這對于向后兼容性很重要:因為比較之類的操作當前回傳整數值,所以無法確定現有應用程式怎么使用這些值,

預計隨著時間的推移,標準庫將在適當的時候更新為使用 False 和 True (但在以前允許使用 int 的場合,則不需要使用 bool 引數型別),此更改不應引起在本 PEP 中未詳細說明的其它問題,

C API

“boolobject.h”頭檔案為布爾型別定義了 C API,它包含在“Python.h”中,因此不需要再 include 它,

現有的名稱 Py_False 和 Py_True 參考獨一無二的布爾物件 False 和 True (之前,它們分別參考了值為 0 和 1 的靜態整數物件,是眾多整數之一),

一個新的 API,即PyObject *PyBool_FromLong(long) ,會接收一個 C 長整型引數,并回傳對 Py_False (當引數為零時)或 Py_True (當非零時)的新參考,

要檢查物件是否為布爾物件,可以使用宏 PyBool_Check(),

布爾實體的型別是 PyBoolObject *,

布爾型別物件可作為 PyBool_Type 使用,

澄清

本 PEP 沒有改變一個事實,即幾乎所有型別的物件都可以用作真偽值,例如,在 if 陳述句中使用時,一個空串列為 false,一個非空串列為 true;這不會改變,而且也不打算改變,

唯一改變的是在回傳或賦值時,用于表示真偽值的首選值,以前,這些首選的真偽值是 1 和 0;本 PEP 將首選值更改為 True 和 False,并修改內置操作以回傳這些首選值,

兼容性

因為要向后兼容,所以布爾型別擁有一些不嚴格的屬性,例如,允許使用布爾引數進行算術運算,即將 False 視為 0,將 True 視為 1,而且,可以將 bool 用作序列物件的索引,

我不認為這是一個問題,也不希望朝這個方向發展語言,我認為,對“布爾性(Booleanness)”的更嚴格的解釋不會使語言更清晰,

兼容性要求的另一個結果是運算式“True and 6”的值為 6,類似地,運算式“ False or None”的值為 None,

“and”和“or”運算子被設計來回傳第一個決定了結果的引數,這點不會改變;特別地,它們不強制要求結果為布爾型別,當然,如果兩個引數都是布林值,那么結果肯定是一個布林值,通過寫“bool(x and y)”,也可以很容易地將其強制轉成布爾型別,

解決了的問題

(另請參見上面的“評審”部分,)

  • 由于 bool 值的 repr() 或 str() 與 int 值不同,因此某些代碼(例如,基于doctest 的單元測驗,以及可能依賴于 “%s”%truth 的資料庫代碼)可能會出錯,解決這個問題很容易(無需顯式參考 bool 型別),并且預計這只會影響非常少量的可以輕松修復的代碼,

  • 其它語言(C99、C ++、Java)均以小寫形式命名常量“false”和“true”,對于Python,我更喜歡遵照現有內置常量的慣例,這些內置常量全部使用駝峰式命名:None 、Ellipsis、NotImplemented (以及所有的內置例外),Python 內置的命名空間全部用小寫字母表示函式和型別,

  • 前面提到過,為了滿足用戶的期望,對于在布爾背景關系中被認為是真的每個 x,x == True 運算式都應該為真,同樣,如果 x 被認為是假,則x == False 也應該為真,那些剛了解布爾變數的新手可能會寫:

    if x == True: ...
    

    而不是正確的形式:

    if x: ...
    

    許多人乍一看會對后一種形式感到不舒服,這在心理和語言上似乎有很強的理由,但是我認為解決辦法應該是教育而不是削弱語言,

    畢竟,== 通常被視為傳遞符號,這意味著根據 a == b 和 b == c,可以推論出 a == c,但是,如果在一個數是真值的情況下,它與 True 進行比較的結果是相等的,則像 6 == True == 7 這樣的暴行將成立,從而可以推斷出錯誤的 6 == 7,那是不可接受的,(此外,它會破壞向后兼容性,但是,即使它不破壞,出于前面的原因,我仍然反對,)

    還應該提醒新手,沒有理由寫:

    if bool(x): ...
    

    因為布林值隱含在“if”中,在這里,顯式并 比隱式好,因為添加的詞法會損害可重用性,并且限制了解釋器的解釋行為,(譯注:”The Zen of Python“中認為”顯式比隱式好“,但在這里,Guido 認為隱式更好,所以他在原檔案中加粗了”not“)

    但是,有時候有理由寫成:

    b = bool(x)
    

    當不需要保留對任意 x 物件的參考時,或者由于某些其它原因需要規范化時,這很有用,有時候這樣寫也很合適:

    i = int(bool(x))
    

    它將布林值轉換為整數的 0 或 1,傳達了將該值用作 int 的意圖,

實作

完整的 C 實作代碼已上傳到 SourceForge 補丁管理器:https://bugs.python.org/issue528022

它將很快被合入到 python 2.3a0 的 CVS 中,

著作權

本檔案已進入公共領域,

源檔案:https://github.com/python/peps/blob/master/pep-0285.txt

更多的 PEP 中文翻譯內容,可在 Github 查閱:https://github.com/chinesehuazhou/peps-cn

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/57015.html

標籤:Python

上一篇:據說存在.bss區段以作為未初始化的變數空間。但為何節表中查不到該區段呢?

下一篇:求助帖!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more