<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                6-二進制-字符串-字符列表 ======================== [UTF-8和Unicode](#61-utf-8%E5%92%8Cunicode) [二進制(和bitstring)](#62-%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%92%8Cbitstring) [字符列表](#63-%E5%AD%97%E7%AC%A6%E5%88%97%E8%A1%A8) 在“基本類型”一章中,介紹了字符串,以及使用```is_binary/1```函數檢查它: ```elixir iex> string = "hello" "hello" iex> is_binary string true ``` 本章將學習理解,二進制(binaries)是個啥,它怎么和字符串扯上關系的。 以及用單引號包裹的值,```'like this'```是啥意思。 ## 6.1-UTF-8和Unicode 字符串是UTF-8編碼的二進制。 為了弄清這句話啥意思,我們要先理解兩個概念:bytes和code point的區別。 字母```a```的code point是97,而字母```?```的code point是322。 當把字符串```"he??o"```寫到硬盤上的時候,需要將其code point轉化為bytes。 如果一個byte對應一個code point,那是寫不了```"he??o"```的, 因為字母```?```的code point是322,超過了一個byte所能存儲的最大數值(255)。 但是如你所見,該字母能夠顯示到屏幕上,說明還是有一定的解決方法的。于是 _編碼_ 便出現了。 要用byte表示code point,我們需要在一定程度上對其進行編碼。 Elixir使用UTF-8為默認編碼格式。 當我們說某個字符串是UTF-8編碼的二進制數據,意思是該字符串是一串byte, 以一定方法組織來表示特定的code points,即UTF-8編碼。 因此當我們存儲字母```?```的時候,實際上是用兩個bytes來表示它。 這就是為什么有時候對同一字符串,調用函數```byte_size/1```和```String.length/1``` 結果不一樣: ```elixir iex> string = "he??o" "he??o" iex> byte_size string 7 iex> String.length string 5 ``` UTF-8需要1個byte來表示code points:h,e和o,用2個bytes表示?。 在Elixir中可以使用```?```運算符獲取code point值: ```elixir iex> ?a 97 iex> ?? 322 ``` 你還可以使用 [String模塊](http://elixir-lang.org/docs/stable/elixir/String.html)里的函數 將字符串切成單獨的code points: ```elixir iex> String.codepoints("he??o") ["h", "e", "?", "?", "o"] ``` Elixir為字符串操作提供了強大的支持。實際上,Elixir通過了文章 [“字符串類型破了”](http://mortoray.com/2013/11/27/the-string-type-is-broken/) 記錄的所有測試。 不僅如此,因為字符串是二進制,Elixir還提供了更強大的底層類型的操作。 下面就來介紹該底層類型---二進制。 ## 6.2-二進制(和bitstring) 在Elixir中可以用```<<>>```定義一個二進制: ```elixir iex> <<0, 1, 2, 3>> <<0, 1, 2, 3>> iex> byte_size <<0, 1, 2, 3>> 4 ``` 一個二進制只是一連串bytes。這些bytes可以以任何方法組織,即使湊不成一個合法的字符串: ```elixir iex> String.valid?(<<239, 191, 191>>) false ``` 字符串的拼接操作實際上是二進制的拼接操作: ```elixir iex> <<0, 1>> <> <<2, 3>> <<0, 1, 2, 3>> ``` 一個常見技巧是,通過給某字符串尾部拼接一個null byte```<<0>>```, 來看看該字符串內部二進制的樣子: ```elixir iex> "he??o" <> <<0>> <<104, 101, 197, 130, 197, 130, 111, 0>> ``` 二進制中的每個數值都表示一個byte,因此其最大是255。 如果超出了255,二進制允許你再提供一個修改器(標識一下那個位置的存儲空間大小)使其可以存儲; 或者將其轉換為utf8編碼后的形式(變成多個byte的二進制): ```elixir iex> <<255>> <<255>> iex> <<256>> # truncated <<0>> iex> <<256 :: size(16)>> # use 16 bits (2 bytes) to store the number <<1, 0>> iex> <<256 :: utf8>> # the number is a code point "ā" iex> <<256 :: utf8, 0>> <<196, 128, 0>> ``` 如果一個byte是8 bits,那如果我們給一個size是1 bit的修改器會怎樣?: ```elixir iex> <<1 :: size(1)>> <<1::size(1)>> iex> <<2 :: size(1)>> # truncated <<0::size(1)>> iex> is_binary(<< 1 :: size(1)>>) false iex> is_bitstring(<< 1 :: size(1)>>) true iex> bit_size(<< 1 :: size(1)>>) 1 ``` 這樣(每個元素是1 bit)就不再是二進制(人家每個元素是byte,至少8 bits)了, 而是bitstring,就是一串比特! 所以實際上二進制就是一串比特,只是比特數是8的倍數。 也可以對二進制或bitstring做模式匹配: ```elixir iex> <<0, 1, x>> = <<0, 1, 2>> <<0, 1, 2>> iex> x 2 iex> <<0, 1, x>> = <<0, 1, 2, 3>> ** (MatchError) no match of right hand side value: <<0, 1, 2, 3>> ``` 注意(沒有修改器標識的情況下)二進制中的每個元素都應該匹配8 bits。 因此上面最后的例子,匹配的左右兩端不具有相同容量,因此出現錯誤。 下面是使用了修改器標識的匹配例子: ```elixir iex> <<0, 1, x :: binary>> = <<0, 1, 2, 3>> <<0, 1, 2, 3>> iex> x <<2, 3>> ``` 上面的模式僅在二進制 **尾部** 元素被修改器標識為又一個二進制時才正確。 字符串的連接操作也是一個意思: ```elixir iex> "he" <> rest = "hello" "hello" iex> rest "llo" ``` 總之,記住字符串是UTF-8編碼的二進制,而二進制是特殊的、數量是8的倍數的bitstring。 這種機制增加了Elixir在處理bits或bytes時的靈活性。 而現實中99%的時候你會用```is_binary/1```和```byte_size/1```函數跟二進制打交道。 ## 6.3-字符列表 字符列表就是字符的列表。 雙引號包裹字符串,單引號包裹字符列表。 ```elixir iex> 'he??o' [104, 101, 322, 322, 111] iex> is_list 'he??o' true iex> 'hello' 'hello' ``` 字符列表存儲的不是bytes,而是字符的code points(實際上就是這些code points的普通列表)。 如果某字符不屬于ASCII返回,iex就打印它的code point。 實際應用中,字符列表常被用來做參數,同一些老的庫,或者同Erlang平臺交互。 因為這些老庫不接受二進制作為參數。 將字符列表和字符串之間轉換,使用函數```to_string/1```和```to_char_list/1```: ```elixir iex> to_char_list "he??o" [104, 101, 322, 322, 111] iex> to_string 'he??o' "he??o" iex> to_string :hello "hello" iex> to_string 1 "1" ``` 注意這些函數是多態的。它們不但轉化字符列表和字符串,還能轉化字符串和整數,等等。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看