精华内容
下载资源
问答
  • 互换的标准类型包括
    2020-09-16 22:03:02

    概念

    在这里,期货就不多做介绍了,介绍下互换。

    互换是指两个或两个以上当事人在约定的时间内,按照商定的条件交换一系列现金流的合约(互换可以看作是一系列远期的组合,远期合约可以看成仅交换一次现金流的互换)

    种类

    • 利率互换:是指双方同意在未来的一定期限内根据同种货币的同样的名义本金交换现金流,其中一方的现金根据浮动利率计算出来,而另一方的现金流根据固定利率计算。
    • 货币互换:是指将一种货币的本金和固定利息与另一货币的等价本金和固定利息进行交换。
    • 商品互换:是一种特殊类型的金融交易,交易双方为了管理商品价格风险,同意交换与商品价格有关的现金流。它包括固定价格及浮动价格的商品价格互换和商品价格与利率的互换。
    • 其它互换:股权互换、信用互换、气候互换和互换期权等。

    其中利率互换和货币互换是最常见也最重要的互换种类。

    有一个国际组织ISDA (International Swaps and Derivatives Association) 国际掉期交易协会.

    掉期和互换的英文都是SWAP,两者有一定的区别。掉期合同是一种协议,规定了合同双方在一定时间段内交换一系列现金流的协议,交换发生在合同预置好的日期,通常只交换现金流净值。外汇掉期是指在外汇市场上买进即期外汇的同时又卖出同种货币的远期外汇,或者卖出即期外汇的同时又买进同种货币的远期外汇,也就是说在同一笔交易中将一笔即期和一笔远期业务合在一起做,或者说在一笔业务中将借贷业务合在一起做。

    掉期交易的操作涉及即期交易与远期交易或买卖的同时进行,类型有即期对远期的掉期交易(spot-forward swaps)一天掉期交易(one-day swaps)远期对远期的掉期交易(forward-forward swaps)。 而互换则是一系列远期的组合。

    对比互换和期货

     期货交易互换交易
    基础相同远期合约是期货和互换的基础,期货和互换是对远期合约在不同方面创新后的衍生工具。因此,远期协议可以被用来给期货定价,也可以被用来给互换定价。
    交易对象标准化程度不同商品品种、数量、质量、等级、交货时间、交货地点等都是标准化的,唯一的变量是价格标的物及其数量、质量、等级均有交易双方自行协商决定,是非标准化合同
    成交方式不同在交易所组织的有形的公开市场内通过电子交易系统撮合成交。价格具有公开性、权威性互换交易一般无固定的交易场所和交易时间,可以在银行间市场或者柜台市场的交易商之间进行,也可以与最终客户直接交易,主要通过人工询价的方式撮合成交。
    合约双方关系不同合约履行不取决于交易对手,而取决于结算机构在期货交易中充当中央对手的角色。期货结算机构是所有买方的卖方,是所有卖方的买方。交易者无须关心交易对手是谁、信用如何,市场信用度很高。交易双方直接签订,一对一,违约风险取决于对手的信用
    更多相关内容
  • 【C语言】枚举类型

    千次阅读 2020-07-09 20:33:21
    当我们在编程中遇到定义一些固定长度或范围的数值时,可以考虑使用枚举类型。使用枚举可以让我们的程序可读性更强、看起来更加直观。举个例子,如果我们在编程中需要使用数字0-6分别表示星期日-星期六,程序的可读性...

    00. 目录

    01. 枚举概述

    **枚举(enum)**是C语言的一种特殊类型。当我们在编程中遇到定义一些固定长度或范围的数值时,可以考虑使用枚举类型。使用枚举可以让我们的程序可读性更强、看起来更加直观。举个例子,如果我们在编程中需要使用数字0-6分别表示星期日-星期六,程序的可读性就不高,我们需要翻手册或者看程序注释才能知道每个数字具体代表什么意思。如果我们使用枚举呢,基本上不需要看注释或手册就可知晓其大意。

    enum week    // enum 枚举类型{枚举值列表};
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    };
    enum week today = SUN; //使用枚举类型定义一个变量
    

    使用enum定义的枚举值列表中,默认值是从0开始,然后依次递增:SUN=0,MON=1…。当然我们也可以显式指定枚举值:

    enum week
    {
        SUN = 1,MON,TUE,WED,THU = 7,FRI,SAT,
    };
    //SUN=1,那么接下来MON=2,TUE=3,WED=4
    //THU=7,那么接下来FRI=8,SAT=9
    

    02. 枚举三种用法

    使用枚举类型定义变量,使用方法跟结构体、共用体类似,经常使用的三种方法如下:

    enum week //定义枚举类型的同时,定义枚举变量
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    }today, tomorrow;
    
    enum //可以省去枚举类型名,直接定义变量
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    }today, tomorrow;
    
    enum week //先定义枚举类型,再定义枚举变量
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    };
    enum week today, tomorrow;
    

    03. 枚举的本质

    在C语言中,枚举是一种类型,属于整型的范畴,使用enum定义的枚举值列表,其实就是从0开始的一系列整数序列。整型除了short、int、long、long long外,还包括char、_Bool(C99标准新增)和enum。因此,枚举的使用其实和整数值其实没啥区别:我们使用枚举类型定义的变量,同样可以作为函数参数、函数返回值、用来定义数组、甚至和结构体混用等。

    enum week get_week_time (void);
    int set_week_time (enum week time_set);
    int change_week_time (enum week *p);
    enum week a[10];
    struct student
    {
        char name[20];
        int age;
        enum week birthday;
    };
    

    枚举有点类似于typedef,给一个数值添加一个别名,让我们的程序更加直观、可读性更高。枚举类型在本质上就是有命名的整数,属于整型的一种,在代码中是可以和整型互换的。

    enum week t = SUN;
    int  t2 = SUN;
    enum week t3 = t2;
    enum week t4 = 100;
    

    在上面的代码中,枚举变量和整型变量相互赋值,都是可以正常编译和运行的。我们在代码中使用枚举类型,在最终编译生成的可执行文件中都会被整型数值代替。

    enum week 
    {
        SUN = 5,MON,TUE,WED,THU,FRI,SAT,
    };
    
    int main (void)
    {
        enum week today = THU;
        return 0;
    }
    

    在上面的示例代码中,我们定义了一个枚举类型week,然后定义了一个枚举变量today,并赋值为THU。反汇编上面的代码,我们可以看到汇编代码:

    00010400 <main>:
       10400:   e52db004    push    {fp}        
       10404:   e28db000    add fp, sp, #0
       10408:   e24dd00c    sub sp, sp, #12
       1040c:   e3a03009    mov r3, #9  
       10410:   e50b3008    str r3, [fp, #-8]
       10414:   e3a03000    mov r3, #0
       10418:   e1a00003    mov r0, r3
       1041c:   e24bd000    sub sp, fp, #0
       10420:   e49db004    pop {fp}        ;
       10424:   e12fff1e    bx  lr
    

    在C程序中定义的枚举变量today,在汇编代码的第1040c处,我们可以看到:枚举值THU被替换为整型数值9。使用枚举的唯一好处就是增加代码的可读性,它的作用跟宏定义的作用有异曲同工之妙。

    04. 枚举与宏

    枚举与预处理指令#define的作用差不多,都是为了增加代码的可读性。但在实际使用中,两者还是有些差别的:宏在预处理阶段,通过简单的字符串替换就全部被替换掉了,编译器根本不知道有宏这么一个玩意;而枚举类型则在编译阶段全部替换为整型。

    跟宏相比,枚举的优势是:枚举可以自动赋值,而宏则需要一个一个单独定义。因此,在自定义一些有规则的类型值的时候,使用枚举会更加方便。枚举可以自定义的变量值来代替数字值,使我们的程序代码有更高的可读性。

    05. 枚举在Linux内核中应用

    在Linux内核代码中,充斥着大量的枚举类型数据,有些枚举类型的定义看起来很奇怪,比如:

    enum 
    {
        MM_FILEPAGES,
        MM_ANONPAGES,
        MM_SWAPENTS,
        NR_MM_COUNTERS
    };
    enum pid_type
    {
        PIDTYPE_PID,
        PIDTYPE_PGID,
        PIDTYPE_SID,
        PIDTYPE_MAX
    };
    

    Linux内核中使用enum定义的枚举类型大部分是没有枚举名的,而且通常会在一串枚举值之后带上一个NR*的元素用来表示枚举值的数量。当我们不需要使用枚举类型去定义一个枚举变量时,枚举并不需要一个名字,这些无名的枚举类型其实就相当于宏定义。而最后一个元素NR或MAX,一般可以用来记载枚举列表中元素的个数,或者作为循环判断的边界值。

    06. 使用枚举需要注意的问题

    什么是类型?类型是一定范围的数值及方法的集合。枚举作为整型类型的一种,在编程使用过程中,也有一些注意的地方,比如作用域。使用枚举定义的常量也遵循数据作用域规:包括文件作用域、代码块作用域等,在同一个作用域能不能出现重名的枚举常量名。

    enum week1
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    };
    enum week2
    {
        SAT,UNKNOW,
    };
    int main (void)
    {   
        return 0;
    }
    

    在上面的代码中,我们定义了两个枚举类型,其中枚举常量SAT重名,编译时就会发生如下错误:

    error: redeclaration of enumerator `SAT'
    error: previous definition of 'SAT' was here
    

    出现错误的原因是,我们定义的不同枚举类型中的两个枚举常量名同在一个作用域:文件作用域,我们稍微改一下代码就可以避免冲突:

    #include <stdio.h>
    enum week1
    {
        SUN,MON,TUE,WED,THU,FRI,SAT,
    };
    int main (void)
    {
        printf("%d\n", SAT);
        enum week2
        {
            SAT,UNKNOW,
        };
        printf("%d\n", SAT);    
        return 0;
    }
    

    我们将枚举类型week2的定义放到了main函数内,week2的作用域就从文件作用域变为代码块作用域。这个时候,两个枚举类型中的同名枚举常量就不会再发生冲突,程序的运行结果为:

    6
    0
    

    07. 附录

    参考:C程序设计

    展开全文
  • 2.Python对象类型 (1)标准类型(基本数据类型) a) .数字(分为几个字类型,其中三个是整型) Integer 整型 Boolean 布尔型 Long integer 长整型 Floating point real number 浮点型 Complex number 复数型 b) ...

    Python认为一切皆为对象;比如我们初始化一个list时:

    li = list('abc')

    实际上是实例化了内置模块builtins(python2中为__builtin__模块)中的list类;

    ContractedBlock.gif

    ExpandedBlockStart.gif

    classlist(object):def __init__(self, seq=()): #known special case of list.__init__

    """list() -> new empty list

    list(iterable) -> new list initialized from iterable's items

    # (copied from class doc)"""

    pass

    View Code

    验证:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    In [1]: li = list('abc')

    In [2]: li.__class__Out[2]: list

    In [3]: li.__class__.__name__Out[3]: 'list'

    View Code

    1. Python对象特性

    python使用对象模型来存储数据。构造任何类型的值都是一个对象。所有python对象都拥有三个特性:身份、类型、值:

    1)身份:每个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数 id() 来得到。

    2)类型:对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。可以使用 type() 函数查看python对象的类型。type()返回的是对象而不是简单的字符串。

    3)值:对象表示的数据。

    python不需要事先声明对象类型,当python运行时,会根据“=“右侧的数据类型来确定变量类型;

    2.Python对象类型

    (1)标准类型(基本数据类型)

    a) .数字(分为几个字类型,其中三个是整型)

    Integer 整型

    Boolean 布尔型

    Long integer 长整型

    Floating point real number 浮点型

    Complex number 复数型

    b) String 字符串

    c) List 列表

    d) Tuple 元祖

    e) Dictionary 字典

    (2)其他内建类型

    类型、Null对象(None)、文件、集合/固定集合、函数/方法、模块、类

    3. 基本对象类型分类

    有3种不同的模型可以帮助我们对基本类型进行分类

    1)存储类型

    999584-20170904122914194-784036549.png

    一个能保存单个字面对象的类型,称为原子或标量存储;可以容纳多个对象的类型,称为容器存储;并且所有的python容器对象都可以容纳不同类型的对象;

    注意,python没有字符类型,所以虽然字符串你看上去像容器类型,实际是原子类型

    2)更新模型(是否可变)

    999584-20170904123415272-67332216.png

    这里所说的是否可变,可更新是针对的对象的值而言的;是在对象身份不变的情况下(id不变),值是否可更新;

    ContractedBlock.gif

    ExpandedBlockStart.gif

    s = 'abc'

    print('id of s:', id(s))

    s= 'xyz'

    print('id of s:', id(s))

    View Code

    结果:

    id of s: 41643960id of s:46319184

    上例中,很多人会说s是字符串,也可变啊,但是注意,这里s指向的对象发生了变化(id值发生了变化),所以这不是我们所说的可更新;让我们看一下list

    ContractedBlock.gif

    ExpandedBlockStart.gif

    li = ['a', 'b']print('li before update', li)print('id of li:', id(li))

    li[0]= 'x'

    print('li after update', li)print('id of li:', id(li))

    View Code

    结果:

    li before update ['a', 'b']

    id of li:48447304li after update ['x', 'b']

    id of li:48447304

    li的值发生了变化,但是li还是原来的对象(id值不变)

    另外,对于元祖,元祖本身不可变,但是当元祖存在可变元素时,元祖的元素可变,比如

    ContractedBlock.gif

    ExpandedBlockStart.gif

    t = (1, ['a','b'])print('t before update', t)print('id of t:', id(t))

    t[1][0] = 'x'

    print('t after update', t)print('id of t:', id(t))

    View Code

    结果:

    t before update (1, ['a', 'b'])

    id of t:48328968t after update (1, ['x', 'b'])

    id of t:48328968

    注意:在使用for循环来遍历一个可更新对象过程中,增加删除可更新对象容器的大小会得到意想不到的结果(不期望的结果)甚至出现异常,其中对于字典,直接报错;

    直接遍历列表:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]2

    3 for item inlst:4 if item ==0:5 lst.remove(item)6 print(lst) #结果为 [1, 1, 2, 8, 3, 2, 5, 0, 2, 6]

    View Code

    遍历索引:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]2

    3 for item inrange(len(lst)):4 if lst[item] ==0:5 dellst[item]6 print(lst) #结果为IndexError: list index out of range

    View Code

    字典:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 dct = {'name':'winter'}2 for key indct:3 if key == 'name':4 di['gender'] = 'male'

    5 print(dct) #结果报错RuntimeError: dictionary changed size during iteration

    View Code

    for循环来遍历可变对象时,遍历顺序在最初就确定了,而在遍历中如果增加删除了元素,更新会立即反映到迭代的条目上,会导致当前索引的变化,这样一是会导致漏删或多增加元素,二是会导致遍历超过链表的长度。那么有解决方案吗?

    a) 通过创建一个新的可变对象实现,比如:

    b) 通过while循环

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #通过创建新的copy

    2 for item inlst[:]:3 if item ==0:4 lst.remove(item)5 print(lst)6 #通过while循环

    7 while 0 inlst:8 lst.remove(0)9 print (lst)

    View Code

    更多的内容,看我关于“迭代器”的博客

    3)访问模型

    999584-20170904125349069-1388507081.png

    序列是指容器内的元素按从0开始的索引顺序访问;

    字典的元素是一个一个的键值对,类似于哈希表;通过获取键,对键执行一个哈希操作,根据计算的结果,选择在数据结构的某个地址中存储你的值。任何一个值的存储地址取决于它的键;所以字典是无序的,键必须是不可变类型(对于元祖,只能是元素不可变的元祖)

    总结:

    999584-20170904130037257-660882088.png

    999584-20170904131605069-2024209824.png

    既然字符串,列表,元祖,字典都是对象,那么任何一种实例化的对象都会有相同的方法,下面让我们来依次来认识这些常见的数据类型:

    4. 字符串

    1)创建字符串

    两种方式:

    #直接创建字符串引用

    s = 'winter'

    #通过使用str()函数创建

    s = str(123)

    2)字符串方法

    作为内建对象,字符串类的定义在内建模块builtins中,通过源码可以查看到所有字符串方法;如果你在用pycharm,那么更加方便,选中str类以后,点击按钮"Scroll from Source";就可以看到所有方法的列表;

    999584-20170905161601882-549924685.png

    针对每一种方法都有详细的方法文档;在这里吐血一一罗列出,有的注释部分很重要:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 '''字符串方法'''

    2

    3 #index,字符串查找,返回第一个匹配到的索引值,没有就报错,可以提供开始,结束位置

    4 s = 'xyzabc'

    5 ret = s.index('za') #结果为2

    6 ret = s.index('z',2) #结果为2

    7 #rindex,反向查找,结果和index方法得到的结果一样

    8 #find,也是字符串查找,与index不同的是找不到时,不会报错,而是返回-1,注意bool(-1)为True

    9

    10

    11 #split,字符串分隔,如果不指定分割符,则默认采用任意形式的空白字符:空格,tab(\t),换行(\n),回车(\r)以及formfeed

    12 res = 'a b c d\ne'.split() #结果res为['a', 'b', 'c', 'd', 'e']

    13 res = 'a:b:c:d'.split(':') #结果为['a', 'b', 'c', 'd']

    14 #rsplit,从字符串尾部开始分割,没有设置maxsplit参数时和split的结果一样

    15 #splitlines用于将多行字符串,列表的每个元素为一行字符串,默认不带换行符

    16

    17

    18 #partition,类似于s.split(sep, 1),只是输出是一个包括了sep的元祖,且没有默认分隔符sep

    19 res = 'a:b:c:d'.partition(':') #结果为('a', ':', 'b:c:d')

    20 #rpartition,从字符串末尾开始执行partition方法

    21 res = 'a:b:c:d'.rpartition(':') #结果为('a:b:c', ':', 'd')

    22

    23

    24 #strip,去掉字符串两端的字符,如果没指定字符,则默认去掉任意形式的空白字符:空格,tab(\t),换行(\n),回车(\r)以及formfeed

    25 res = 'abcd'.strip('a') #结果res为'bcd'

    26 res = 'abcd \n'.strip() #结果res为'abcd',可以通过len(res)验证

    27 #rstrip,去掉右端的字符

    28 #lstrip,去掉左端的字符

    29

    30

    31 #join,字符串拼接

    32 #format,字符串格式化

    33 #解决万恶的‘+’号,每次'+'操作都会创建一个新的对象,就需要在内存空间开辟一块新的区域来存储;所以大量使用'+'会浪费内存空间

    34 #解决方法1,使用join

    35 #join,字符串拼接

    36 li = ['a', 'b']37 res = ':'.join(li) #使用字符串来拼接一个可迭代对象的所有元素,结果res为'a:b'

    38 #解决方法2,使用format,有两种方式:

    39 #方式1,其中{0}可以简写为{}:

    40 res = 'my name is {0}, my age is {1}'.format('winter',30) #{0},{1}为实参的索引

    41 #方式2:

    42 res = 'my name is {name}, my age is {age}'.format(name='winter', age=30)43 #或者直接下面这样

    44 userInfo = {'name':'winter','age':30}45 res = 'my name is {name}, my age is {age}'.format(**userInfo)46 #或者用format_map(python3.x新增)

    47 userInfo = {'name':'winter','age':30}48 res = 'my name is {name}, my age is {age}'.format_map(userInfo)49 #解决方法3,除了format以外,还可以使用占位符%,看上去没那么高级,同样有两种方式

    50 #方式1

    51 res = 'my name is %s, my age is %s'%('winter',30)52 #方式2

    53 userInfo = {'name':'winter','age':30}54 res = 'my name is %(name)s, my age is %(age)s'%userInfo55 #结果为'my name is winter, my age is 30'

    56

    57 #replace,字符串替换,因为字符串为不可变数据类型,所以原字符串不会改变,改变的字符串以返回值形式返回

    58 s = '123xyz'

    59 ret = s.replace('1','a') #结果s不变,ret为'a23xyz'

    60 ret = s.replace('12', 'ab') #结果为'ab3xyz'

    61

    62

    63 #maketrans和translate,一对好基友;用于字符串替换和删除,很好用,python2.x与python3.x语法不同

    64 #maketrans用于创建翻译表,translate用于翻译表

    65 s = 'abccba'

    66 trans_table = str.maketrans('ab','12','c')67 res = s.translate(trans_table) #结果为'1221',注意与replace的区别

    68

    69

    70 s.count(strings) #count,统计字符串中字符的数目

    71

    72

    73 s.encode() #以某种编码格式编码,比如utf-8

    74

    75

    76 #大小写切换类方法

    77 s = 'aBcD'

    78 res = s.capitalize() #首字母大写,结果res为'Abc'

    79 res = s.lower() #所有字母小写,结果res为'abcd',注意仅对ASCII编码的字母有效

    80 res = s.casefold() #所有字母小写,结果res为'abcd',注意对unicode编码的字母有效

    81 res = s.upper() #所有字母大写,结果res为'ABCD'

    82 res = s.swapcase() #字符串中大小写互换,结果res为'AbCd'

    83 s = 'aB cD,ef'

    84 res = s.title() #每个单词首字母大写,结果res为'Ab Cd,Ef',其判断“单词”的依据则是基于空格和标点

    85

    86

    87 #字符串判断类方法,以下方法除了isspace()以外,对于空字符串都返回False

    88 s.isalpha() #判断字符串是否全为字母,等价于^[a-zA-Z]+$

    89 s.islower() #判断字符串中字母部分是否全为小写字母,可以有其他字符,但是至少要有一个小写字母,等价于[a-z]+

    90 s.isupper() #判断字符串中字母部分是否全为小写字母,可以有其他字符,但是至少要有一个小写字母,等价于[A-Z]+

    91 s.istitle() #判断字符串首字母是否全为大写,可以有其他字符

    92 s.isnumeric() #判断字符串是否全为数字(包括unicode数字,罗马数字,汉字数字)

    93 s.isdigit() #也是判断字符串是否全为数字(包括unicode数字,罗马数字)

    94 s.isdecimal() #判断字符串是否全为十进制数字(包括unicode数字)

    95 s.isalnum() #判断字符串是否为数字与字母的组合,等价于^[0-9a-zA-Z]+$

    96 s.isidentifier() #判断标识符是否合法

    97 s.isspace() #判断是否为任意形式的空白字符:空格,tab(\t),换行(\n),回车(\r)以及formfeed

    98 s.isprintable() #判断字符串是否可打印

    99 s.startswith(strings) #判断字符串是否以某个字符串开头

    100 s.endswith(stings) #判断字符串是否以某个字符串结尾

    101

    102

    103 #center,ljust,rjust,zfill字符串排版,填充

    104 s = '123'

    105 res = s.center(50,'-') #center是字符串居中,结果为-----------------------123------------------------

    106 #ljust为居左,rjust为居右,zfill使用0来左填充

    107

    108

    109 s.expandtabs() #expandtables,用于将字符串中的tab字符转换为空格,如果没有指定tabsize,默认为8个

    View Code

    5. 列表

    1)创建列表

    三种方式:

    a = ['a','b','c'] #直接创建

    b = list('abc') #通过创建list实例创建,结果为['a','b','c']

    c = [x for x in range(4)]  #列表推导式,结果为[1,2,3,4]

    注意,第二种方法,我们来看一下它的构造函数:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    def __init__(self, seq=()): #known special case of list.__init__

    """list() -> new empty list

    list(iterable) -> new list initialized from iterable's items

    # (copied from class doc)"""

    pass

    View Code

    接收的参数是一个可迭代对象,即拥有__iter__方法的对象,元祖,集合和字典的构造函数的参数都是可迭代对象;

    第三种方法称为列表推导式,语法为

    [expr for iter_var in iterable] #迭代iterable里所有内容,每一次迭代,都把iterable里相应内容放到iter_var中,再在表达式中应用该iter_var的内容,最后用表达式的计算值生成一个列表。

    扩展形式

    [expr for iter_var in iterable if cond_expr] #加入了判断语句

    2)列表方法

    与查看字符串方法类似,可以通过源码查看,这里也一一罗列出:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #增,append,insert,extend

    2 #追加append

    3 li = ['a','b','c']4 li.append('d') #结果li = ['a','b','c','d'],list是可变类型,所以li元素的增加删除会影响源列表

    5 #插入insert

    6 li = ['a','b','c']7 li.insert(1,'d') #结果li = ['a','d','b','c']

    8 #extend,将一个可迭代对象增加追加到列表里

    9 li = ['a','b','c']10 li.extend(['x','y']) #结果li = ['a','b','c','x','y']

    11 li.extend(('m','n')) #结果li = ['a', 'b', 'c', 'x', 'y', 'm', 'n']

    12

    13

    14 #删,remove,pop,clear

    15 #remove,删除第一个与参数值相等的元素,删除不存在的元素报ValueError

    16 li = ['a','b','c','a']17 li.remove('a') #结果li = ['b', 'c', 'a']

    18 #pop,参数为索引值,弹出对应索引值的元素,返回值为弹出的元素,默认为弹出最后一个元素,索引不存在报IndexError

    19 li = ['a','b','c','a']20 res = li.pop(1) #结果res = ‘b',li = ['a', 'c', 'a']

    21 #clear,清空列表,但是列表对象依然存在,没有被回收

    22 li = ['a','b','c','a']23 li.clear() #结果li = []

    24

    25

    26 #查,count,index

    27 #count,统计列表内元素个数

    28 li = ['a','b','c','a']29 res = li.count('a') #结果res = 2

    30 #index,查找元素对应的索引值,不存在报ValueError

    31 li = ['a', 'b', 'c', 'a']32 res = li.index('a') #结果res = 0

    33

    34

    35 #reverse,反转

    36 li = ['a','b','c']37 li.reverse() #结果li = ['c','b','a']

    38

    39

    40 #sort,根据key排序,默认从小到大,同样可以实现反转

    41 li = ['c','b','a']42 li.reverse() #结果li = ['a', 'b', 'c']

    43 li = [[4,5,6], [7,2,5], [6,1,8]]44 li.sort(key=lambda x:x[1]) #结果li = [[6, 1, 8], [7, 2, 5], [4, 5, 6]],根据li元素的第二个值进行排序

    45

    46

    47 #copy,浅复制,注意与赋值和深复制的区别

    48 li = [[1,2,3], 'a']49 li_new =li.copy()50 li_new[0][0] = 4 #li_new = [[4, 2, 3], 'a'],但是li也发生了变化li = [[4, 2, 3], 'a']

    51 li_new[1] = 'b' #li_new = [[1, 2, 3], 'b'],但是li不变,[[1, 2, 3], 'a']

    View Code

    6. 元祖

    1)创建元祖

    两种方式:

    t = (1,2,3) #直接创建

    t = tuple([1,2,3]) #通过tuple函数创建,参数为可迭代对象,结果为(1,2,3)

    2)元祖方法

    和字符串,一样,通过源码查看,这里一一列出:

    ContractedBlock.gif

    ExpandedBlockStart.gif

    #count,统计元祖内元素个数

    t = (1,2,3,1)

    res= t.count(1) #结果res = 2

    #index,查找元素对应的索引值,不存在报ValueError

    t = (1,2,3,1)

    res= t.index(1) #结果res = 0

    View Code

    元祖的方法很少,而且元祖对象是不可变的,元组不可变的好处。保证数据的安全,比如我们传数据到一个不熟悉的方法或者数据接口, 确保方法或者接口不会改变我们的数据从而导致程序问题。

    注意,因为()处理用于定义元祖,还可以作为分组操作符,比如if ( a> b) and (a < c)中的(),且python遇到()包裹的单一元素,首先会认为()是分组操作符,而不是元组的分界符,所以一般我们对于元组,会在)之前再加入一个,

    a = (1,2,3,)

    3) 列表vs元组

    使用不可变类型变量的情况:如果你在维护一些敏感数据,并且需要把这些数据传递给一个不了解的函数(或一个根本不是你写的API),作为一个只负责一个软件某一部分的工程师,如果你希望你的数据不要被调用的函数篡改,考虑使用不可变类型的变量;

    需要可变类型参数的情况:管理动态数据集合时,你需要先创建,然后渐渐地不定期地添加,或者有时需要移除一些单个的元素,这时必须使用可变类型对象;将可变类型变量作为参数传入函数,在函数内可以对参数进行修改,可变类型变量也会相应修改;

    7. 序列共有特性

    字符串,列表,元祖统称序列,是可以顺序访问的;他们的关系和共有特性如下:

    1)相互转换

    999584-20170911225627188-228469707.png

    2)序列操作符

    999584-20170911230223703-2095845011.png

    a)根据索引取值,可以正向索引,也可以反向索引

    999584-20170911231247594-113407559.png

    ContractedBlock.gif

    ExpandedBlockStart.gif

    li = [1,2,3,4]

    res= li[0] #结果为1

    res = li[-1] #结果为4

    li[1] = ['a'] #结果li = [1,'a',3,4]

    View Code

    b)切片

    seq[ind1:ind2:step],原则是顾头不顾尾

    ContractedBlock.gif

    ExpandedBlockStart.gif

    li = [1,2,3,4]

    res= li[:] #结果为[1, 2, 3, 4]

    res = li[1:] #结果为[2,3,4]

    res = li[:-2] #结果为[1,2]

    res = li[1:3] #结果为[2,3]

    res = li[::2] #取索引值为偶数的元素[1,3],对应的li[1::2]为取索引值为基数的元素

    res = li[::-1] #步进为-1,结果为[4, 3, 2, 1]

    res = li[-1:-3:-1] #结果为[4,3]

    res = li[3:1:-1] #结果为[4,3]

    res = li[1:1] #结果为[]

    li[1:2] = ['a','b'] #结果li = [1, 'a', 'b', 3, 4]

    li[1:1] = [9] #结果li = [1, 9, 'a', 'b', 3, 4],相当于插入

    View Code

    注意序列不能读写不存在的索引值,但是切片可以

    ContractedBlock.gif

    ExpandedBlockStart.gif

    li = [1,2,3]

    li[9] #报IndexError

    li[1:9] #结果为[2,3]

    li[8:9] = [9] #结果为[1,2,3,9]

    View Code

    c)重复操作符*

    ContractedBlock.gif

    ExpandedBlockStart.gif

    [1]*3 #结果为[1,1,1]

    [1,2,3]*3 #结果为[1, 2, 3, 1, 2, 3, 1, 2, 3]

    View Code

    d)连接操作符+

    ContractedBlock.gif

    ExpandedBlockStart.gif

    [1,2,3]+[4,5,6] 结果为 [1, 2, 3, 4, 5, 6]

    View Code

    e)成员关系操作符in, no in

    ContractedBlock.gif

    ExpandedBlockStart.gif

    li = [1,2,3]1 in li #结果为True

    4 not in li #结果为True

    View Code

    f)删除序列对象,元素关键字del

    ContractedBlock.gif

    ExpandedBlockStart.gif

    l = [1,2,3]del l[0] #结果l为[2,3]

    del l #结果访问l后,报NameError

    View Code

    3)可操作内建函数

    999584-20170912225852078-971982014.png

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #enumerate,枚举

    2 li = ['a','b','c']3 for item inenumerate(li):4 print(item)5 '''

    6 结果为:7 (0, 'a')8 (1, 'b')9 (2, 'c')10 '''

    11 for item in enumerate(li,5):12 print(item)13 '''

    14 结果为:15 (5, 'a')16 (6, 'b')17 (7, 'c')18 '''

    19

    20

    21 #len

    22 len([1,2,3]) #结果为3

    23 len([[1,2],[3,4]]) #结果为2

    24

    25

    26 #max, min

    27 max([1,2,3]) #结果为3

    28 min([1,2,3]) #结果为1

    29

    30

    31 #sorted,注意与list.sort()方法的区别

    32 li = [[1,4],[2,3],[3,2]]33 res = sorted(li, key=lambda x:x[1]) #结果res为[[3, 2], [2, 3], [1, 4]]

    34

    35

    36 #zip,和倒置有点像

    37 l1 = [1,2,3]38 l2 = [1,2,3]39 for item inzip(l1,l2):40 print(item)41 '''

    42 结果为:43 (1, 1)44 (2, 2)45 (3, 3)46 '''

    47 l1 = [1,2,3]48 l2 = [1,2]49 for item inzip(l1,l2):50 print(item)51 '''

    52 结果为:53 (1, 1)54 (2, 2)55 '''

    View Code

    8. 字典

    字典是Python语言中唯一的映射类型。映射对象类型里哈希值(键,key)和指向的对象(值,value)是一对多的关系;

    特性:

    a)字典是无序的可变的容器类型

    b)字典的键是唯一的,且必须是不可变类型,如果是元组,要求元组的元素也不可变(因为值的内存地址与键的哈希值有关)

    1)创建字典

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #直接创建

    2 d ={3 'name':'winter',4 'age':18,5 'hobbies':['basketball','football']6 }7

    8 #通过dict函数创建,参数为可迭代对象,字典或列表组成的任意形式;[(),()]或((),())或([],[])或[[],[]]或使用dict(zip())

    9 d = dict([('name', 'winter'),10 ('age',18),11 ('hobbies',['basketball','football'])]) #结果为{'age': 18, 'hobbies': ['basketball', 'football'], 'name': 'winter'}

    12

    13 #通过字典推导式

    14 d = {x:y for x, y in zip(['name','age','hobbies'],['winter',18,['basketball','football']])} #结果为{'age': 18, 'hobbies': ['basketball', 'football'], 'name': 'winter'}

    15 d = {x:y for x, y in zip(['name','age','hobbies'],['winter',18,['basketball','football']]) if x=='name'}#结果为{'name': 'winter'}

    16

    17 #通过字典方法fromkeys()创建一个含有默认值的字典,fromkeys方法是dict类的静态方法

    18 d = dict.fromkeys(['name','gender'], 'unknown') #结果{'gender': 'unknown', 'name': 'unknown'}

    View Code

    2)字典方法

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #增

    2 d ={3 'name':'winter',4 'age':18,5 'hobbies':['basketball','football']6 }7 #update,类似于list.extend(),将键值对参数加到字典中,对于已存在的更新

    8 d.update({'gender':'male'}) #结果为:{'age': 18, 'gender': 'male', 'hobbies': ['basketball', 'football'], 'name': 'winter'}

    9

    10

    11 #删

    12 d ={13 'name':'winter',14 'age':18,15 'hobbies':['basketball','football']16 }17 #popitem,随机删除一组键值对,并返回该组键值对

    18 res = d.popitem() #结果为res = ('hobbies', ['basketball', 'football']), d为{'age': 18, 'name': 'winter'}

    19 #pop,删除指定键的键值对,返回对应的值

    20 res = d.pop('name') #结果为res = 'winter', d为{'age': 18}

    21 #clear,清空字典,字典对象还在,没有被回收

    22 d.clear() #结果d为{}

    23 #del关键字,可以用于删除字典对象和元素

    24 d ={25 'name':'winter',26 'age':18,27 'hobbies':['basketball','football']28 }29 del d['hobbies'] #结果为 {'age': 18, 'name': 'winter'}

    30 del d #结果访问d,报NameError

    31

    32

    33 #查

    34 d ={35 'name':'winter',36 'age':18,37 'hobbies':['basketball','football']38 }39 #get,根据键取对应的值,没有对应的键,就返回第二个参数,默认为None

    40 res = d.get('name', 'not found') #res = ’winter'

    41 res = d.get('gender', 'not found') #res = 'not found'

    42 #setdefault,根据键取对应的值,如果不存在对应的键,就增加键,值为第二个参数,默认为None

    43 res = d.setdefault('name','winter') #res = ’winter'

    44 res = d.setdefault('gender','male') #res = 'male',d变为{'age': 18, 'gender': 'male', 'hobbies': ['basketball', 'football'], 'name': 'winter'}

    45 #keys,获得所有的键

    46 res = d.keys() #res = dict_keys(['name', 'age', 'hobbies', 'gender'])

    47 #values,获得所有的值

    48 res = d.values() #res = dict_values(['winter', 18, ['basketball', 'football'], 'male'])

    49 #items,获得所有的键值对

    50 res = d.items() #res = dict_items([('name', 'winter'), ('age', 18), ('hobbies', ['basketball', 'football']), ('gender', 'male')])

    51

    52

    53 #copy方法, 和list.copy一样,是浅复制

    View Code

    3)字典元素的访问

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 dic = {'name':'winter', 'age':18}2 '''

    3 下面3中方式的结果都为4 name winter5 age 186 '''

    7 #方式1

    8 for item indic:9 print(item, dic[item])10 #方式2

    11 for item indic.keys():12 print(item, dic[item])13 #方式3

    14 for k,v indic.items():15 print(k, v)

    View Code

    推荐方式1),采用了迭代器来访问;

    4)字典vs列表

    a) 字典:

    查找和插入的速度极快,不会随着key的数目的增加而增加(直接查找hash后得到的内存地址);

    需要占用大量的内存,内存浪费多(大量的hash值,占用内存你空间)

    key不可变

    默认无序

    b) 列表:

    查找和插入的时间随着元素的增加而增加

    占用空间小,浪费内存很少

    通过下标查询

    有序

    9. 集合

    这是高一数学的内容了

    集合对象是一组无序排列的值,分为可变集合(set)和不可变集合(frozenset);可变集合不可hash;不可变集合可以hash,即可以作为字典的键;

    特性:

    a) 无序性,无法通过索引访问

    b) 互异性,元素不可重复,即有去重的功能

    1) 创建集合

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #直接创建可变集合

    2 s1 = {1,2,3,3} #结果,python3.x为{1,2,3},python2.x为set([1, 2, 3]),因为集合不允许有重复元素,所以只有一个3元素

    3 #通过函数创建

    4 s2 = set([1,2,3,4]) #创建可变集合{1, 2, 3, 4}

    5 s3 = frozenset([1,2,3,3]) #创建不可变集合,结果为frozenset({1, 2, 3})

    View Code

    2) 集合方法和操作符

    这里直接用一张表:

    999584-20170918145710978-482956260.png

    这里只列出可变集合的方法示例,因为不可变集合的方法可变集合都有

    a) 单个集合的操作

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 #集合

    2

    3 #直接创建可变集合

    4 s1 = {1,2,3,3} #结果,python3.x为{1,2,3},python2.x为set([1, 2, 3]),因为集合不允许有重复元素,所以只有一个3元素

    5 #通过函数创建

    6 s2 = set([1,2,3,4]) #创建可变集合{1, 2, 3, 4}

    7 s3 = frozenset([1,2,3,3]) #创建不可变集合,结果为frozenset({1, 2, 3})

    8

    9

    10 s1 = {1,2,3}11

    12 #增

    13 s1.add('456') #结果s1 = {1, 2, 3, '456'}

    14 s1.update('789') #结果s1 = {1, 2, 3, '7', '8', '9', '456'}

    15

    16 #删

    17 res = s1.pop() #结果res = 1,s1 = {2, 3, '7', '8', '9', '456'}

    18 s1.remove(3) #结果s1 = {2, '7', '8', '9', '456'}

    19 s1.discard(4) #结果s1 = {2, '7', '8', '9', '456'},同时不报Error

    20 s1.clear() #结果s1 = set()

    21

    22 #浅复制

    23 s1 = {1,2,3}24 s2 = s1.copy() #结果s2 = {1,2,3}

    View Code

    b) 集合之间的操作,集合的主要功能

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 s0 = {1,2}2 s1 = {1,2,3,4}3 s2 = {3,4,5,6}4

    5 #子集,超级判断

    6 res = s0.issubset(s1) #结果res = True

    7 res = s1.issubset(s2) #结果res = False

    8 res = s1.issuperset(s0) #结果res = True

    9 res = s0 <= s1 #结果res = True

    10

    11 #并集

    12 res = s1.union(s2) #结果res = {1, 2, 3, 4, 5, 6}

    13 res = s1 | s2 #结果res = {1, 2, 3, 4, 5, 6}

    14

    15 #交集

    16 res = s1.intersection(s2) #结果为{3, 4}

    17 res = s1 & s2 #结果为{3, 4}

    18

    19 #差集

    20 res = s2.difference(s1) #结果res = {5, 6}

    21 res = s2 - s1 #结果res = {5, 6}

    22 res = s1.difference(s2) #结果res = {1, 2}

    23

    24 #对称差集

    25 res = s2.symmetric_difference(s1) #结果为{1, 2, 5, 6}

    26 res = s2 ^ s1 #结果为{1, 2, 5, 6}

    27

    28 #在原集合基础上修改原集合

    29 s1.intersection_update(s2)30 s1.difference_update(s2)31 s1.symmetric_difference_update(s2)

    View Code

    用一张图来解释一下:

    999584-20170918161637525-1916430665.png

    2017年9月20日更新

    1. 推导式

    有列表推导式,字典推导式,集合推导式

    1)列表推导式

    ContractedBlock.gif

    ExpandedBlockStart.gif

    1 li_1 = [item for item in range(5)] #结果li_1 = [0, 1, 2, 3, 4]2

    3 li_2 = [item for item in range(5) if item > 2] #结果li_2 = [3, 4]4

    5 li_3 = [item if item>2 else 0 for item in range(5)] #结果li_3 = [0, 0, 0, 3, 4]6

    7 li_4 = [(x,y) for x in range(3) for y in range(3,6)] #结果li_4 = [(0, 3), (0, 4), (0, 5), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)]8

    9 li_raw = [['winter', 'tom', 'lily'], ['winter']]10 li_5 = [item for li in li_raw for item in li if item.count('l') > 1] #结果li_5 = ['lily']

    View Code

    2)集合推导式

    和列表推导式一样,只要把[]换成{}即可

    3)字典推导式

    和列表推导式一样,只是没有if...else...形式

    4)有元祖推导式吗?

    (x for x in range(5))就是元祖推导式呢?

    答案是:不是的

    (x for x in range(5)得到的是一个生成器

    >>>a = (x for x in range(10))>>>a>>> at 0x0000000004B09F68>

    >>>a.__next__()

    >>>0

    >>>a.__next__()

    >>>1

    展开全文
  • 文章目录1、数据类型1.1、数值类型1.1.1、整型(整数类型)1.1.2、浮点型(小数类型)1.1.3、复数1.2、bool类型(布尔类型)1.3、字符串类型1.3.1、定义字符串1.3.2、字符串拼接符“+”1.3.3、字符串实现基于 UTF-8 ...

    1、数据类型

    1.1、数值类型

    数值类型分为以下几种:整数、浮点数、复数。

    1.1.1、整型(整数类型)

    Go语言提供了有符号和无符号的整数类型,其中包括 int8、int16、int32 和 int64 四种大小截然不同的有符号整数类型,分别对应 8、16、32、64 bit(二进制位)大小的有符号整数,与此对应的是 uint8、uint16、uint32 和 uint64 四种无符号整数类型。

    用来表示 Unicode 字符的 rune 类型和 int32 类型是等价的,通常用于表示一个 Unicode 码点。这两个名称可以互换使用。同样,byte 和 uint8 也是等价类型,byte 类型一般用于强调数值是一个原始的数据而不是一个小的整数。最后,还有一种无符号的整数类型 uintptr,它没有指定具体的 bit 大小但是足以容纳指针。

    尽管在某些特定的运行环境下 int、uint 和 uintptr 的大小可能相等,但是它们依然是不同的类型,比如 int 和 int32,虽然 int 类型的大小也可能是 32 bit,但是在需要把 int 类型当做 int32 类型使用的时候必须显示的对类型进行转换,反之亦然。

    1.1.2、浮点型(小数类型)

    Go语言提供了两种精度的浮点数 float32 和 float64。
    一个 float32 类型的浮点数可以提供大约 6 个十进制数的精度,而 float64 则可以提供约 15 个十进制数的精度,通常应该优先使用 float64 类型,因为 float32 类型的累计计算误差很容易扩散,并且 float32 能精确表示的正整数并不是很大。例如:

    var f float32 = 16777216 // 1 << 24
    fmt.Println(f == f+1)    // "true"!
    

    浮点数在声明的时候可以只写整数部分或者小数部分,像下面这样:

    const e = .71828 // 0.71828
    const f = 1.     // 1
    

    很小或很大的数最好用科学计数法书写,通过 e 或 E 来指定指数部分:

    const Avogadro = 6.02214129e23  // 阿伏伽德罗常数
    const Planck   = 6.62606957e-34 // 普朗克常数
    

    用 Printf 函数打印浮点数时可以使用“%f”来控制保留几位小数,例如:

    fmt.Printf("%f\n", math.Pi)		//3.141593
    fmt.Printf("%.2f\n", math.Pi)	//3.14
    

    1.1.3、复数

    复数是由两个浮点数表示的,其中一个表示实部(real),一个表示虚部(imag)。Go语言中复数的类型有两种,分别是 complex128(64 位实数和虚数)和 complex64(32 位实数和虚数),其中 complex128 为复数的默认类型。

    复数的值由三部分组成 RE + IMi,其中 RE 是实数部分,IM 是虚数部分,RE 和 IM 均为 float 类型,而最后的 i 是虚数单位。
    声明复数的语法格式如下所示:

    var name complex128 = complex(x, y)
    

    其中 name 为复数的变量名,complex128 为复数的类型,“=”后面的 complex 为Go语言的内置函数用于为复数赋值,x、y 分别表示构成该复数的两个 float64 类型的数值,x 为实部,y 为虚部。

    上面的声明语句也可以简写为下面的形式:

    name := complex(x, y)
    

    对于一个复数z := complex(x, y),可以通过Go语言的内置函数real(z)来获得该复数的实部,也就是 x;通过imag(z)获得该复数的虚部,也就是 y。例如:

    var x complex128 = complex(1, 2) // 1+2i
    var y complex128 = complex(3, 4) // 3+4i
    fmt.Println(x*y)                 // "(-5+10i)"
    fmt.Println(real(x*y))           // "-5"
    fmt.Println(imag(x*y))           // "10"
    

    复数也可以用==!=进行相等比较,只有两个复数的实部和虚部都相等的时候它们才是相等的。
    Go语言内置的 math/cmplx 包中提供了很多操作复数的公共方法,实际操作中建议大家使用复数默认的 complex128 类型,因为这些内置的包中都使用 complex128 类型作为参数。

    1.2、bool类型(布尔类型)

    一个布尔类型的值只有两种:true 或 false。if 和 for 语句的条件部分都是布尔类型的值,并且==<等比较操作也会产生布尔型的值。

    一元操作符!对应逻辑非操作,因此!true的值为 false,更复杂一些的写法是(!true == false) == true,实际开发中我们应尽量采用比较简洁的布尔表达式,就像用 x 来表示x==true

    Go语言对于值之间的比较有非常严格的限制,只有两个相同类型的值才可以进行比较,如果值的类型是接口(interface),那么它们也必须都实现了相同的接口。如果其中一个值是常量,那么另外一个值可以不是常量,但是类型必须和该常量类型相同。如果以上条件都不满足,则必须将其中一个值的类型转换为和另外一个值的类型相同之后才可以进行比较。

    布尔值可以和 &&(AND)和 ||(OR)操作符结合,并且有短路行为,如果运算符左边的值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值,因此下面的表达式总是安全的:

    s != "" && s[0] == 'x'	// 其中 s[0] 操作如果应用于空字符串将会导致 panic 异常。
    

    1.3、字符串类型

    字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容,更深入地讲,字符串是字节的定长数组。

    1.3.1、定义字符串

    可以使用双引号""来定义字符串,字符串中可以使用转义字符来实现换行、缩进等效果,常用的转义字符包括:\n:换行符、\r:回车符、\t:tab 键、\u 或 \U:Unicode 字符、\:反斜杠自身。
    例如:

    var str = "C语言中文网\nGo语言教程"
    

    字符串的内容(纯字节)可以通过标准索引法来获取,在方括号[]内写入索引,索引从 0 开始计数:

    • 字符串 str 的第 1 个字节:str[0]
    • 第 i 个字节:str[i - 1]
    • 最后 1 个字节:str[len(str)-1]

    需要注意的是,这种转换方案只对纯 ASCII 码的字符串有效。
    注意:获取字符串中某个字节的地址属于非法行为,例如 &str[i]。

    1.3.2、字符串拼接符“+”

    两个字符串 s1 和 s2 可以通过 s := s1 + s2 拼接在一起。将 s2 追加到 s1 尾部并生成一个新的字符串 s。

    可以通过下面的方式来对代码中多行的字符串进行拼接:

    str := "Beginning of the string " + "second part of the string"
    

    提示:因为编译器会在行尾自动补全分号,所以拼接字符串用的加号“+”必须放在第一行末尾。

    也可以使用“+=”来对字符串进行拼接:

    s := "hel" + "lo,"
    s += "world!"
    fmt.Println(s) //输出 “hello, world!”
    

    1.3.3、字符串实现基于 UTF-8 编码

    Go语言中字符串的内部实现使用 UTF-8 编码,通过 rune 类型,可以方便地对每个 UTF-8 字符进行访问。当然,Go语言也支持按照传统的 ASCII 码方式逐字符进行访问。

    1.3.4、定义多行字符串

    在Go语言中,使用双引号书写字符串的方式是字符串常见表达方式之一,被称为字符串字面量(string literal),这种双引号字面量不能跨行,如果想要在源码中嵌入一个多行字符串时,就必须使用`反引号,代码如下:
    在这里插入图片描述
    代码运行结果:
    在这里插入图片描述

    在 `间的所有代码均不会被编译器识别,而只是作为字符串的一部分。

    1.4、字符类型(byte和rune)

    1.4.1、概念

    字符串中的每一个元素叫做“字符”,在遍历或者单个获取字符串元素时可以获得字符。
    字符有以下两种:

    • 一种是 uint8 类型,或者叫 byte 型,代表了 ASCII 码的一个字符。
    • 另一种是 rune 类型,代表一个 UTF-8 字符,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型。rune 类型等价于 int32 类型。

    下面的写法是等效的:

    var ch byte = 65var ch byte = '\x41'      // \x 总是紧跟着长度为 2 的 16 进制数
    

    另外一种可能的写法是 \后面紧跟着长度为 3 的八进制数,例如 \377。

    Go语言同样支持 Unicode(UTF-8),因此字符同样称为 Unicode 代码点或者 runes,并在内存中使用 int 来表示。在文档中,一般使用格式 U+hhhh 来表示,其中 h 表示一个 16 进制数。

    在书写 Unicode 字符时,需要在 16 进制数之前加上前缀\u或者\U。因为 Unicode 至少占用 2 个字节,所以我们使用 int16 或者 int 类型来表示。如果需要使用到 4 字节,则使用\u前缀,如果需要使用到 8 个字节,则使用\U前缀。

    var ch int = '\u0041'
    var ch2 int = '\u03B2'
    var ch3 int = '\U00101234'
    fmt.Printf("%d - %d - %d\n", ch, ch2, ch3) // integer: 65 - 946 - 1053236
    fmt.Printf("%c - %c - %c\n", ch, ch2, ch3) // character: A - β - r
    fmt.Printf("%X - %X - %X\n", ch, ch2, ch3) // UTF-8 bytes: 41 - 3B2 - 101234
    fmt.Printf("%U - %U - %U", ch, ch2, ch3)   // UTF-8 code point: U+0041 - U+03B2 - U+101234
    

    1.4.2、UTF-8 和 Unicode 的区别

    Unicode 与 ASCII 类似,都是一种字符集。

    字符集为每个字符分配一个唯一的 ID,我们使用到的所有字符在 Unicode 字符集中都有一个唯一的 ID,例如上面例子中的 a 在 Unicode 与 ASCII 中的编码都是 97。汉字“你”在 Unicode 中的编码为 20320,在不同国家的字符集中,字符所对应的 ID 也会不同。而无论任何情况下,Unicode 中的字符的 ID 都是不会变化的。

    UTF-8 是编码规则,将 Unicode 中字符的 ID 以某种方式进行编码,UTF-8 的是一种变长编码规则,从 1 到 4 个字节不等。编码规则如下:

    • 0xxxxxx 表示文字符号 0~127,兼容 ASCII 字符集。
    • 从 128 到 0x10ffff 表示其他字符。

    根据这个规则,拉丁文语系的字符编码一般情况下每个字符占用一个字节,而中文每个字符占用 3 个字节。

    广义的 Unicode 指的是一个标准,它定义了字符集及编码规则,即 Unicode 字符集和 UTF-8、UTF-16 编码等。

    2、类型转换

    2.1、类型转换的概念

    类型 B 的值 = 类型 B(类型 A 的值)
    

    在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明:

    a := 5.0
    b := int(a)
    

    浮点数在转换为整型时,会将小数部分去掉,只保留整数部分。

    2.2、字符串和数值类型的相互转换

    开发时往往需要对一些常用的数据类型进行转换,如 string、int、int64、float 等数据类型之间的转换,Go语言中的 strconv 包为我们提供了字符串和基本数据类型之间的转换功能。strconv 包中常用的函数包括 Atoi()、Itia()、parse 系列函数、format 系列函数、append 系列函数等。

    2.2.1、string 与 int 类型之间的转换

    字符串和整型之间的转换是我们平时编程中使用的最多的,下面就来介绍一下具体的操作。

    • Itoa():整型转字符串

    Itoa() 函数用于将 int 类型数据转换为对应的字符串类型,函数签名如下func Itoa(i int) string,如:

    func main() {
        num := 100
        str := strconv.Itoa(num)
        fmt.Printf("type:%T value:%#v\n", str, str) // type:string value:"100"
    }
    
    • Atoi():字符串转整型

    Atoi() 函数用于将字符串类型的整数转换为 int 类型,函数签名func Atoi(s string) (i int, err error)。通过函数签名可以看出 Atoi() 函数有两个返回值,i 为转换成功的整型,err 在转换成功是为空转换失败时为相应的错误信息,如:

    func main() {
        str1 := "110"
        str2 := "s100"
        num1, err := strconv.Atoi(str1)
        if err != nil {
            fmt.Printf("%v 转换失败!", str1)
        } else {
            fmt.Printf("type:%T value:%#v\n", num1, num1)
        }
        num2, err := strconv.Atoi(str2)
        if err != nil {
            fmt.Printf("%v 转换失败!", str2)
        } else {
            fmt.Printf("type:%T value:%#v\n", num2, num2)
        }
    }
    

    结果:

    type:int value:110
    s100 转换失败!
    

    2.2.2、Parse 系列函数

    Parse 系列函数用于将字符串转换为指定类型的值,其中包括 ParseBool()、ParseFloat()、ParseInt()、ParseUint()。

    2.2.2.1、ParseBool()

    ParseBool() 函数用于将字符串转换为 bool 类型的值,它只能接受 1、0、t、f、T、F、true、false、True、False、TRUE、FALSE,其它的值均返回错误,函数签名:func ParseBool(str string) (value bool, err error)
    示例如下:

    func main() {
        str1 := "110"
        boo1, err := strconv.ParseBool(str1)
        if err != nil {
            fmt.Printf("str1: %v\n", err)
        } else {
            fmt.Println(boo1)
        }
        str2 := "t"
        boo2, err := strconv.ParseBool(str2)
        if err != nil {
            fmt.Printf("str2: %v\n", err)
        } else {
            fmt.Println(boo2)
        }
    }
    

    结果如下:

    str1: strconv.ParseBool: parsing "110": invalid syntax
    true
    

    2.2.2.2、ParseInt()

    ParseInt() 函数用于返回字符串表示的整数值(可以包含正负号),函数签名:func ParseInt(s string, base int, bitSize int) (i int64, err error)。参数说明:

    • base 指定进制,取值范围是 2 到 36。如果 base 为 0,则会从字符串前置判断,“0x”是 16 进制,“0”是 8 进制,否则是 10 进制。
    • bitSize 指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64。
    • 返回的 err 是 *NumErr 类型的,如果语法有误,err.Error = ErrSyntax,如果结果超出类型范围 err.Error = ErrRange。

    示例代码如下:

    func main() {
        str := "-11"
        num, err := strconv.ParseInt(str, 10, 0)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(num)
        }
    }
    

    运行结果如下:

    -11
    

    2.2.2.3、ParseUnit()

    ParseUint() 函数的功能类似于 ParseInt() 函数,但 ParseUint() 函数不接受正负号,用于无符号整型,函数签名:func ParseUint(s string, base int, bitSize int) (n uint64, err error)。示例代码如下:

    func main() {
        str := "11"
        num, err := strconv.ParseUint(str, 10, 0)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(num)
        }
    }
    

    运行结果如下:

    11
    

    2.2.2.4、ParseFloat()

    ParseFloat() 函数用于将一个表示浮点数的字符串转换为 float 类型,函数签名: func ParseFloat(s string, bitSize int) (f float64, err error)。参数说明:

    • 如果 s 合乎语法规则,函数会返回最为接近 s 表示值的一个浮点数(使用 IEEE754 规范舍入)。
    • bitSize 指定了返回值的类型,32 表示 float32,64 表示 float64;
    • 返回值 err 是 *NumErr 类型的,如果语法有误 err.Error=ErrSyntax,如果返回值超出表示范围,返回值 f 为 ±Inf,err.Error= ErrRange。

    示例代码如下:

    func main() {
        str := "3.1415926"
        num, err := strconv.ParseFloat(str, 64)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(num)
        }
    }
    

    运行结果如下:

    3.1415926
    

    Parse 系列函数都有两个返回值,第一个返回值是转换后的值,第二个返回值为转化失败的错误信息。

    2.2.3、Format 系列函数

    Format 系列函数实现了将给定类型数据格式化为字符串类型的功能,其中包括 FormatBool()、FormatInt()、FormatUint()、FormatFloat()。

    2.2.3.1、FormatBool()

    FormatBool() 函数可以一个 bool 类型的值转换为对应的字符串类型,函数签名:func FormatBool(b bool) string。示例代码如下:

    func main() {
        num := true
        str := strconv.FormatBool(num)
        fmt.Printf("type:%T,value:%v\n ", str, str)
    }
    

    运行结果如下:

    type:string,value:true
    

    2.2.3.2、FormatInt()

    FormatInt() 函数用于将整型数据转换成指定进制并以字符串的形式返回,函数签名: func FormatInt(i int64, base int) string。其中,参数 i 必须是 int64 类型,参数 base 必须在 2 到 36 之间,返回结果中会使用小写字母“a”到“z”表示大于 10 的数字。示例代码如下:

    func main() {
        var num int64 = 100
        str := strconv.FormatInt(num, 16)
        fmt.Printf("type:%T,value:%v\n ", str, str)
    }
    

    运行结果如下:

    type:string,value:64
    

    2.2.3.3、FormatUint()

    FormatUint() 函数与 FormatInt() 函数的功能类似,但是参数 i 必须是无符号的 uint64 类型,函数签名: func FormatUint(i uint64, base int) string。示例代码如下:

    func main() {
        var num uint64 = 110
        str := strconv.FormatUint(num, 16)
        fmt.Printf("type:%T,value:%v\n ", str, str)
    }
    

    运行结果如下:

    type:string,value:6e
    

    2.2.3.4、FormatFloat()

    FormatFloat() 函数用于将浮点数转换为字符串类型,函数签名:func FormatFloat(f float64, fmt byte, prec, bitSize int) string。参数说明:

    • bitSize 表示参数 f 的来源类型(32 表示 float32、64 表示 float64),会据此进行舍入。
    • fmt 表示格式,可以设置为“f”表示 -ddd.dddd、“b”表示 -ddddp±ddd,指数为二进制、“e”表示 -d.dddde±dd 十进制指数、“E”表示 -d.ddddE±dd 十进制指数、“g”表示指数很大时用“e”格式,否则“f”格式、“G”表示指数很大时用“E”格式,否则“f”格式。
    • prec 控制精度(排除指数部分):当参数 fmt 为“f”、“e”、“E”时,它表示小数点后的数字个数;当参数 fmt 为“g”、“G”时,它控制总的数字个数。如果 prec 为 -1,则代表使用最少数量的、但又必需的数字来表示 f。

    示例代码如下:

    func main() {
        var num float64 = 3.1415926
        str := strconv.FormatFloat(num, 'E', -1, 64)
        fmt.Printf("type:%T,value:%v\n ", str, str)
    }
    

    运行结果如下:

    type:string,value:3.1415926E+00
    

    2.2.4、Append 系列函数

    Append 系列函数用于将指定类型转换成字符串后追加到一个切片中,其中包含 AppendBool()、AppendFloat()、AppendInt()、AppendUint()。

    Append 系列函数和 Format 系列函数的使用方法类似,只不过是将转换后的结果追加到一个切片中。

    示例代码如下:

    package main
    import (
        "fmt"
        "strconv"
    )
    func main() {
        // 声明一个slice
        b10 := []byte("int (base 10):")
      
        // 将转换为10进制的string,追加到slice中
        b10 = strconv.AppendInt(b10, -42, 10)
        fmt.Println(string(b10))
        b16 := []byte("int (base 16):")
        b16 = strconv.AppendInt(b16, -42, 16)
        fmt.Println(string(b16))
    }
    

    运行结果如下:

    int (base 10):-42
    int (base 16):-2a
    

    3、运算符的优先级

    运算符是用来在程序运行时执行数学或逻辑运算的,在Go语言中,一个表达式可以包含多个运算符,当表达式中存在多个运算符时,就会遇到优先级的问题,此时应该先处理哪个运算符呢?这个就由Go语言运算符的优先级来决定的。
    比如对于下面的表达式:

    var a, b, c int = 16, 4, 2
    d := a + b*c
    

    对于表达式a + b * c,如果按照数学规则推导,应该先计算乘法,再计算加法;b * c的结果为 8,a + 8的结果为 24,所以 d 最终的值也是 24。实际上Go语言也是这样处理的,先计算乘法再计算加法,和数据中的规则一样,读者可以亲自验证一下。

    先计算乘法后计算加法,说明乘法运算符的优先级比加法运算符的优先级高。所谓优先级,就是当多个运算符出现在同一个表达式中时,先执行哪个运算符。

    Go语言有几十种运算符,被分成十几个级别,有的运算符优先级不同,有的运算符优先级相同,请看下表。

    优先级分类运算符结合性
    1逗号运算符,从左到右
    2赋值运算符=、+=、-=、*=、/=、 %=、 >=、 <<=、&=、^=、|=从右到左
    3逻辑或||从左到右
    4逻辑与&&从左到右
    5按位或|从左到右
    6按位异或^从左到右
    7按位与&从左到右
    8相等/不等==、!=从左到右
    9关系运算符<、<=、>、>=从左到右
    1位移运算符<<、>>从左到右
    1加法/减法+、-从左到右
    1乘法/除法/取余*(乘号)、/、%从左到右
    1单目运算符!、*(指针)、& 、++、–、+(正号)、-(负号)从右到左
    1后缀运算符( )、[ ]、->从左到右

    注意:优先级值越大,表示优先级越高。

    一下子记住所有运算符的优先级并不容易,还好Go语言中大部分运算符的优先级和数学中是一样的,大家在以后的编程过程中也会逐渐熟悉起来。如果实在搞不清,可以加括号。

    展开全文
  • C51编译器支持的数据类型(1)

    千次阅读 2021-05-22 18:09:12
    1.1 C-51 编译器支持下列数据类型:数 据 类 型长 度值 域bit1 字节0 或 1signed char1 字节-128~+127unsigned char1 字节0~255signed int2 字节-32768~+32867unsigned int2 字节0~65535signed long4 字节-...
  • C语言-基本数据类型

    千次阅读 2022-05-11 15:26:34
    C语言的基本数据类型
  • 三大资产类型

    千次阅读 2021-02-09 16:36:27
    资产类型可分为:权益类、固收类和现金类。 1、权益类资产 一般我们指的权益类资产,主要包括股票、股票基金、混合基金、及各类凭证(信托、私募股权基金)等。 2、固收类资产 这一类资产,顾名思义,其收益相对...
  • MySQL int类型

    万次阅读 2021-03-03 21:27:17
    在本教程中,您将了解MySQL INT或整数数据类型以及如何在数据库表设计中使用它。 另外,我们将向您展示如何使用表中整数列的显示宽度和ZEROFILL属性。...MySQL支持所有标准SQL整数类型INTEGER、INT和SMAL...
  • ❤ 挑战C站最强C++ STL标准库总结(内含大量示例)

    万次阅读 多人点赞 2021-07-06 20:39:56
    2.vector 容器 2.1 vector基本概念 2.2 vector构造函数 2.3 vector赋值操作 2.4 vector容量和大小 2.5 vector插入和删除 2.6 vector数据存取 2.7 vector互换容器 2.8 vector预留空间 3.deque 容器 3.1 deque容器基本...
  • 数据类型及其表现形式

    千次阅读 多人点赞 2021-09-13 22:55:58
    前言 本文主述:讲述C语言基础知识,对...尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或..
  • python六大数据类型详解

    万次阅读 多人点赞 2019-10-13 21:07:18
    史上最全数据类型详解,详细介绍了Python3 中六个标准的数据类型:Number(数值)、String(字符串)、List(列表)、Tuple(元组)、Set(集合)、Dictionary(字典)。六大数据类型的方法和常规操作。
  • C++基础:变量和基本类型

    千次阅读 2019-12-14 18:49:21
    C++定义了一套包括算术类型(arithmetic type) 和空类型(void) 在内的基本数据类型。其中算术类型包含了字符、整型数、布尔值和浮点数。空类型不对应具体的值,仅用于一些特殊的场合,例如最常见的是,当函数不返回...
  • Python中有6种标准的数据类型:数字(Number)、字符串(String)、列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)。上述6种数据类型可分为两类:不可变数据类型:数字、字符串、元组。可变数据类型:列表、集合...
  • C标准介绍

    千次阅读 2020-04-07 23:48:13
    标准 (ANSI C, POSIX, SVID, XPG, ...) ANSI C:这一标准是 ANSI(美国国家标准局)于 1989 年制定的 C 语言标准。 后来被 ISO(国际标准化组织)接受为标准,因此也称为 ISO C。 ANSI C 的目标是为各种操作系统上的...
  • 超硬核!数据结构学霸笔记,考试面试吹牛就靠它

    万次阅读 多人点赞 2021-03-26 11:11:21
    (仅仅取决于逻辑特性,与其在计算机内部如何表示和实现无关) 定义抽象数据类型的一种格式: ADT name{ 数据对象:<> 数据关系:<> 基本操作:<> }ADT name 算法:是对特定问题求解步骤的一种描述。 算法五个特性:...
  • 作者:Matt Hansen,Aaron Blasdel和Camilo Buscaron (机器翻译) ...机器人操作系统(ROS)是用于机器人开发的开源软件框架,包括中间件,驱动程序,库,工具以及机器人常用的算法。AWS RoboMaker和许多其他与A
  • IOT语义互操作性之标准与开源

    千次阅读 2018-02-20 00:00:00
    UnifiedPOS (UPOS):UPOS 是一个全球采用的互操作性标准, 包括30多个销售点(POS)周边设备类(例如, 现金抽屉、收据打印机等)的 uml 定义的数据模型。 这些数据模型可以在 UPOS 控制和服务层中互操作。 开放连接基金会...
  • 今天突然发现自己在windows下是以管理员身份运行的,为了安全考虑,通过下面操作将我自己的账户切换为标准用户: 首先,管理员身份运行命令行(激活系统管理员): net user Administrator /active:yes 登录...
  • 数字图像的基本类型

    千次阅读 2019-09-16 21:20:29
    数字图像的基本类型 本文讲解10种图像文件的类型和相应的扩展名,主要参考: https://blog.hubspot.com/insiders/different-types-of-image-files. https://www.jianshu.com/p/4d8cace82028. ... Vecto...
  • 题目:服务业组织实施多项服务标准,理论上既包括服务业组织实施自建的服务标准体系的情况,同时还包括服务业组织实施多项“互不相干”的标准的情况。 答案: A、对 B、错 题目:以下哪项 不 属于“服务质量特性”...
  • ERC-1155 标准

    万次阅读 2021-10-11 11:37:17
    ERC-1155 以太坊上的一种代币标准,由 Enjin 首席技术官 Witek Radomski 等人开发,并于 2018 年 6 月 17 日将该标准的第一个版本放置到 Ethereum 的 GitHub 库中,ERC-1155 是 ERC-20 和 ERC-721 的升级规范,它...
  • 研发部软件开发国家标准

    千次阅读 2019-10-07 23:49:31
    软件工程国家标准分为六大类 1、 专业基础标准 2、 过程标准 3、 质量标准 4、 技术与管理标准 5、 工具与方法标准 6、 数据标准 大纲将软件工程标准分为4大类: 1、 基础标准软件工程术语信息处理 数据...
  • STL标准模板库

    千次阅读 2021-12-28 16:28:43
    因此为了建立一种数据结构和算法的统一标准,于是就有了STL. (一)STL的基本概念: 1.STL从广义上可以分为容器,算法,迭代器 2.容器和算法之间通过迭代器进行无缝连接 3.STL几乎所有的代码都采用了模板类型或者...
  • 104通讯规约笔记.docx

    2019-08-20 16:08:34
    标准适用于具有编码串行比特数据传输的远动设备和系统,用以对地理广域过程的监视和控制,指定远动配套标准的目的是使兼容的远动设备之间达到互换。本配套标准利用了国标标准IEC60870-5的系列文件。本标准规范了...
  • 数据传输类型与通信方式

    千次阅读 2021-06-01 16:20:29
    数据传输类型 数据在计算机中是以离散的二进制数字信号表示,但是在数据通信过程中,它是以数字信号方式还是以模拟信号方式表示,主要取决于选用的通信信道所允许传输的信号类型。 如果通信信道不允许直接传输计算机...
  • 主板知识详解:芯片组和支持CPU类型

    千次阅读 2021-07-26 03:27:28
    主板知识详解:芯片组和支持CPU类型1、芯片组芯片组(Chipset)是主板的核心组成部分。如果说中央处理器(CPU)是整个电脑系统的心脏,那么芯片组将是整个身体的躯干。在电脑界,称设计芯片组的厂家为“Core Logic”。...
  • I/O接口标准

    千次阅读 2018-08-08 11:18:25
    I/O接口标准 1.单端信号接口标准 LVTTL和LVCMOS(JESD8-5,JESD8-B) SSTL(JESD8-8,JESD8-9B,JESD8-15) HSTL(JESD8-6) LVTTL和LVCMOS结构通常是简单的push-pull。最简单的例子就是CMOS反向器,需要...
  • 生物信息学习的正确姿势NGS系列文章包括NGS基础、在线绘图、转录组分析(Nature重磅综述|关于RNA-seq你想知道的全在这)、ChIP-seq分析(ChIP-seq基本分析流...
  • 一、值,类型和运算符 原文:Values, Types, and Operators 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 在机器的表面之下,程序在运转...
  • DICOM标准概要

    千次阅读 2019-08-14 16:27:40
    1.DICOM标准英文文档https://www.dicomstandard.org/current/...3.DICOM标准文件内容概要 DICOM(Digital Imaging and Communications in Medicine)医学数字成像和通信 重点在2——9 第一部分:引言与概述,简要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,523
精华内容 8,609
热门标签
关键字:

互换的标准类型包括