Day05-Object-COC特有语法

1. 继承的本质

1. 创建1个对象, 这个对象在内存中是如何分配的
    1). 子类对象中有自己的属性和所有父类的属性
    2). 代码段中的每个类都有1个叫做isa的指针, 这个指针指向它的父类, 一直指到NSObject
    [p1 sayHi];//假设p1是Person对象
    先根据p1指针找到p1指向的对象, 然后根据对象的isa指针找到Person类
    搜索Person类中是否有这个sayHi方法, 如果有执行
    如果没有, 就根据类的isa指针找父类
    NSObject 中如果没有就报错

2. 类的本质

1. 内存中的五大区域
    栈
    堆
    BSS段
    数据段
    代码段:用来存储代码的
    类加载, 当类第一次被访问的时候, 这个类就会被加载到代码段存储起来
2. 三个问题
    1). 类什么时候加载到代码段
        类第一次被访问的时候, 类就会被加载到代码段存储, 类加载
    2). 类以什么样的形式存储在代码段中
    3)类一旦被加载到代码段后, 什么时候回收
        是不会被回收, 除非程序结束
3. 类是以什么样的形式存储在代码段的
    1). 任何存储在内存中的数据都有1个数据类型
        int num =12;
        任何在内存中申请的空间也有自己的类型
        Person *p1 = [Person new];
    2). 在代码段存储类的那块空间是个什么类型的
        在代码段中存储类的步骤
        a. 现在代码段中创建1个Class对象, Class是Foundation框架中的1个类
        这个Class对象就是用来存储类信息的
        b. 将类的信息存储在这个Class对象中
        这个Class对象, 至少有3个属性
        类名: 存储的这个类的名称
        属性们:存储的这个类具有哪些属性
        方法们:存储的这个类具有哪些方法
        所以, 类是Class对象的形式存储在代码段的
        存储类的这个Class对象, 我们也叫做类对象, 用来存储类的1个对象
        所以, 存储类的类对象也有1个叫做isa指针的属性, 这个指针指向存储父类的类对象
4. 如何拿到存储在代码段中的类对象
    1). 调用类的类方法 class 就可以得到存储类的类对象的地址
    2).调用对象的对象方法 class 就可以的到存储这个对象所属的类的Class对象的地址
    3). 对象中的isa指针的值其实就是代码段中存储类的类对象的地址
    注意:
    声明Class指针的时候, 不需要加* 因为typedef的时候已经加了*
5. 如何使用类对象
    1). 拿到存储类的对象以后
        Class c1 = [Person class];
        c1对象就是Person类
        c1完全等价于 Person
    2). 使用类对象来调用类的类方法
        因为类对象就代表存储在这个类对象中的类
        Class c1 = [Person class];
        c1就代表Person类.
        所以在使用Person的地方完全可以使用c1代替
        比如我们使用类名来调用类方法
        [Person sayHi];
        完全可以使用c1来调用, 因为c1就是Person
        [c1 sayHi];
    3). 可以使用类对象来调用new方法, 创建存储在类对象中的类的对象
        Person *p1 =[Person new];
        Class c1 = [Person class];
        其实创建Person对象, 也可以这么做.
        Person *p2 = [c1 new];
    4)注意:
        使用类对象 只能调用类的类方法, 因为类对象就等价于存在其中的类
        Class c1 = [Person class];
        c1就是Person
        1.类是以Class对象的形式存储在代码段中的
        2.如何拿到存储类的类对象
        3.有什么用?
        可以使用类对象调用类的类方法
        Class c1 = [Person class];
        要调用Person的类方法, 可以使用Person去调用, 也可以使用c1去调用

3.SEL

1.SEL全称叫做 selector选择器
    SEL是1个数据类型,所以要在内存中申请空间存储数据
    SEL其实是1个类, SEL对象是用来存储1个方法的
2. 类是以Class对象的形式存储在代码段中
    类名:存储的这个类的类名, NSString
    还要将方法存储在类对象之中, 如何将方法存储在类对象之中
    1). 先创建1个SEL对象
    2).将方法的信息存储在这个SEL对象之中
    3).再将这个SEL对象作为类对象的属性
3. 拿到存储方法的SEL对象
    1).因为SEL是1个typedef类型的, 在自定义的时候已经加了*  所以在声明SEL指针的时候, 不需要加*
    2)取到存储方法的SEL对象
    SEL s1 = @selector(方法名);
4.调用方法的本质:
    [p1 sayHi]
    内部的原理:
    1). 先拿到存储sayHi方法的SEL对象, 也就是拿到存储sayHi方法的SEL数据,SEL消息
    2). 将这个SEL消息发送给p1对象
    3). 这个时候,p1对象接收到这个SEL消息后, 就知道要调用方法
    4).根据对象的isa指针找到存储类的类对象
    5).找到这个类对象后,在这个类对象中去搜索是否有和传入的SEL数据相匹配的,如果有就执行, 如果没有就再找父类, 直到NSObject
    OC最重要的1个机制:消息机制
    调用方法的本质其实就是为对象发送SEL消息
    [p1 sayHi];为p1对象发送1条sayHi消息
5.重点掌握:
    1).方法是以SEL对象的形式存储起来的
    2).如何拿到存储方法的SEL对象
6.手动的为对象发送SEL消息
    1). 先得到方法的SEL数据
    2). 将这个SEL消息发送给p1对象
    调用对象的方法, 将SEL数据发送给对象
    -(id)performSelector:(SEL)aSelector;
    Person *p1 = [Person new];
    SEL s1 = @selector(sayHi);
    [p1 performSelector:s1];与[p1 sayHi]效果是完全一样的
    3).调用1个对象的方法有两种
        1).[对象名 方法名];
        2)手动的为对象发送SEL消息
7.注意事项:
    1).如果方法有参数, 那么方法名是带了冒号的
    2).如果方法有参数,如何传递参数,那么就调用另外的方法
    -(id)performSelector:(SEL)aSelector withObject:(id)object;
    -(id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
    3).如果有多个参数

4.点语法

1. java C# 对象可以使用点语法来访问对象的成员,
    oc中也有点语法, OC中也可以使用点语法来访问对象的属性
    但是OC的点语法和Java C#是完全不一样的
    OC的对象如果要为属性赋值或者取值 就要调用对应的getter或者setter
2.使用点语法来访问对象的属性
    语法:
    对象名.去掉下划线的属性名;
    p1.name = @"jack";这个时候就会将@"jack"赋值给p1对象的name属性
    NSString *name = p1.name;把p1对象的_name属性的值取出来
3. 点语法的原理
    p1.age = 18;
    这句话的本质并不是把18直接赋值给p1对象的_age属性
    点语法在编译器编译的时候, 其实会将点语法转换为调用setter, getter的代码
    1).当使用点语法赋值的时候, 这个时候编译器会将点语法转换为调用setter方法的代码.
        对象名.去掉下划线的属性名=数据;
        转换为:
        [对象名 set去掉下划线的属性名首字母大写:数据];
        p1.age=10;
        [p1 setAge:10];
    2). 当使用点语法取值的时候, 这个时候编译器会将点语法转换为调用getter方法的代码.
        对象名.去掉下划线的属性名;
        转换为:
        [对象名 去掉下划线的属性名];
        int age = p1.age;
        int age = [p1 age];
4. 注意:
    1). 在getter 和setter中慎用点语法, 因为有可能造成无限递归 而程序奔溃
    2).点语法在编译器编译的时候, 会转换为调用setter getter方法的代码
    p1.name = @"jack";
    [p1 setName:@"jack"];
    NSString *name = p1.name;
    NSString *name = [p1 name];
    如果我们的setter方法和getter方法名不符合规范 那么点语法就会出问题
    3). 如果属性没有封装getter setter是无法使用点语法的, 因为点语法的本质是getter setter方法

5.@property

1. 我们写1个类.
    a.要先为类写属性
    b.在声明属性的getter setter
    c.再实现getter setter
    重复工作
2.@property
    1). 作用:自动生成getter setter方法的声明
    因为是生成方法的声明,所以应该写在@interface类的声明之中
    2).语法:
    @property 数据类型 名称;
    @property int age;
    3).原理:
    编译器在编译的时候, 会根据@property生成getter 和setter方法的实现
    @property 数据类型 名称;
    生成为:
    -(void)set首字母大写的名称:(数据类型)名称;
    -(数据类型)名称;
    @property int age;
    -(void)setAge:(int)age;
    -(int)age;
3.使用@property注意
    1).@property的类型和属性的类型一致.
    @property的名称和属性的名称一致(去掉下划线)
    2).@property的名称决定了生成的getter和setter方法的名称
    所以,@property的名称要和属性的名称一致,去掉下划线, 否则生成的方法名就是不符合规范的
    @property的数据类型决定了生成的setter方法的参数类型和getter方法的返回值类型
    3).@property只是生成getter和setter方法的声明,实现还要自己来, 属性还要自己定义

6. @synthesize

1.@property只能生成getter和setter的声明
    实现还要自己来写, 繁琐
2.@synthesize
    1).作用:自动生成getter setter方法的实现
    2).语法:
        @synthesize @property名称;
        @interface Person :NSObject{
            int _age;
        }
        @property int age;
        @end
        @implementation Person
        @synthesize age;
        @end
    3).@synthesize 做的事情
        @implementsize Person
        @synthesize age;
        @end
        @implementation Person
        {
            int age;
        }
        -(void)setAge:(int)age{
            self->age = age;
        }
        -(int)age{
            return age;
        }
        @end
        a.生成1个真私有的属性, 属性的类型和@synthesize对应的@property类型一致
        属性的名字和@synthesize对应的@property名字一致
        b.自动生成setter方法的实现
        实现的方式:将参数直接赋值给自动生成的那个私有属性并且没有做任何的逻辑验证
        c.自动生成getter方法的实现.
        实现方式:将生成的私有属性的值返回
    3.希望@synthesize不要去自动生成私有的属性了
        getter setter的实现中操作我们已经写好的属性就可以了
        语法:
        @synthesize @property名称=已经存在的属性名;
        @synthesize age =age
        1).不会再去生成私有属性
        2).直接生成setter getter的实现
        setter的实现:把参数的值直接赋值给指定的属性
        getter的实现:直接返回给指定的属性的值
    4.注意:
        1). 如果直接写1个@synthesize
        @synthesize name;
        2).如果指定操作的属性
        @synthesize name =_name;
        3)生成的setter方法实现中, 是没有做任何逻辑验证的, 是直接赋值
        生成的getter方法的实现中, 是直接返回属性的值
        如果setter或者getter有自己的逻辑验证,那么就自己再类的实现中重写就可以了
    5.批量声明
        1).如果多个@property的类型一致, 可以批量声明
        @property float height,weight;
        2)@synthesize 也可以批量声明
        @synthesize name = _name,age=_age;

7.@property增强

1.@property只是生成getter setter的声明
    @synthesize是生成getter setter的实现
    这种写法是Xcode 4.4之前的写法, 从Xcode4.4以后对@property做了1个增强
2.@property增强
    只需要写1个@property编译器就会自动
    1).生成私有属性
    2).生成getter setter的声明
    3).生成getter setter的实现
    @property NSString *name;
    做的事情
    1)自动的生成1个私有属性,属性的类型和@property类型一致, 属性的名称和@property的名称一致 属性的名称自动的加1个下划线
    2).自动的生成这个属性的getter setter方法的声明
    3).自动的生成这个属性的getter setter 方法的实现
    setter 的实现:直接将参数赋值给自动生成的私有属性
    getter的实现:直接返回生成的私有属性的值
3.使用注意:
    1).@property的类型一定要和属性的类型一致
    名称要和属性的名称一致, 只是去掉下划线
    2). 也可以批量声明相同类型的@property
    3).@property 生成的方法实现没有做任何逻辑验证
    setter:直接赋值
    getter:直接返回
    所以我们可以重写setter来自定义验证逻辑,如果重写了setter还会自动生成getter, 如果重写了getter还会自动生成setter
    如果同时重写getter setter那么就不会自动生成私有属性了
4. 如果你想为类写个属性, 并且为这个属性封装getter setter
    1个@property就搞定
5.继承
    父类的@property一样可以被子类继承
    @property生成的属性是私有的, 在子类的内部无法直接访问生成的私有属性
    但是可以通过setter getter来访问.

8. 动态类型和静态类型

1.oc是1门弱语言
    编译器在编译时,语法检查的时候没有那么严格
    不管你怎么写都是可以的
    int num = 12.12;
    优点:灵活
    缺点:太灵活
    强类型的语言:编译器在编译的时候, 做语法检查的时候, 行就是行, 不行就是不行
2. 静态类型
    值得是1个指针指向的对象是1个类本身
    动态类型:指的是1个指针指向的对象不是类本身
3.编译检查
    编译器在编译的时候, 能不能通过1个指针去调用指针指向的对象的方法
    判断原则:看指针所属的类型之中是有这个方法,如果有就认为可以调用, 编译通过
    如果没有,那么就编译报错
    这个叫做编译检查, 在编译的时候, 能不能调用对象的方法主要是看指针的类型
    我们可以将指针的类型做转换, 来达到编译器的目的
4.运行检查
    编译检查只是骗过了编译器, 但是这个方法究竟能不能执行
    所以在运行的时候, 运行时会去检查对象中是否真的有这个方法, 如果有就执行, 如果没有就报错
5. LSP
    父类指针指向子类对象
    实际上任意的指针可以执行任意的对象,编译器是不会报错的
    当1个子类指针执行1个对象的时候, 编译器运行通过子类指针去调用子类独有的方法,但是在运行的时候是会出问题的,因为父类对象中没有子类成员

9 id类型

1. NSObject: 是OC中所有类的基类, 根据LSP NSObject指针可以指向任意的OC对象
    所以,NSObject指针是个万能指针, 可以执行任意的OC对象
    缺点:如果要调用指向的子类抽象的独有的方法,就必须要做类型转换
2. id指针
    是个万能指针,可以指向任意的OC对象
    1).id是个typedef自定义的类型, 在定义的时候已经加了*
    所以, 声明id指针的时候不需要再加*了
    2).id指针是个万能指针, 任意的OC对象都可以指
3. NSObject和id的异同
    相同点:万能指针, 都可以执行任意的OC对象
    不同点:通过NSObject纸质去调用对象的方法的时候, 编译器会做编译检查
    通过id类型的指针去调用对象的方法的时候, 编译器直接通过, 无论你调用什么方法
    注意:id指针只能调用对象的方法, 不能使用点语法, 如果使用点语法就会直接编译报错
    如果我们要声明1个万能指针,千万不要使用NSObject, 而是使用id
4. 父类中的类方法创建1个父类对象的放回
    1). 如果返回值写为父类类型的, 那么子类来调用这个方法得到就是父类指针
    解决方法:把返回值改为id类型
    2).方法的内部创建的对象的是不要写死, 因为写死创建的对象就固定了
    我们希望哪个类来调用这个方法就创建那个类的对象
    把类名写为self 那个类来调用这个方法 self就指的是那个类, 创建的就是那个类的对象
    3).方法的返回值是id类型的, 问题就是任意指针都可以接收这个方法的返回值
    如果方法的返回值是instancetype
    代表方法的返回值是当前这个类的对象
5. 使用建议
    1). 如果方法内部是在创建当前类的对象, 不要写死成类名, 而是用self代替类名
    2).如果方法的返回值是当前类的对象,也不要写死, 而是写instancetype
6. id和instancetype的区别
    1).instancetype只能作为方法的返回值,不能再别的地方使用
    id即可以声明指针变量,也可以作为参数,也可以作为返回值
    2).instancetype是个有类型的, 代表当前类的对象
    id是个无类型的指针, 仅仅是个地址, 没有类型的指针

10 动态类型检测

1.编译检查
    编译器在编译的时候, 判断1个指针是否可以调用指向的对象的方法
    判断的准则就是指针的类型
    LLVM
2. 就算骗过了编译器, 程序在运行的时候还会做运行检查
    我们写的程序就算编译通过了, 不意味着可以完美的执行
3. 我们就希望, 我们可以写代码来先判断下, 对象中是否有这个方法, 如果有再去执行, 没有就不去执行
    1). 判断对象中是否有这个方法可以执行
    -(BOOL) respondsToSelector:(SEL)aSelector;
    最常用的是这个方法
    2).判断类中是否有指定的类方法
    +(BOOL)instancesRespondToSelector:(SEL)aSelector;
    3).判断指定的对象是否为指定类的对象或者子类对象
    -(BOOL)isKindOfClass:(Class)aClass;
    BOOL b1 = [s1 isJKindOfClass:[Person class]];
    判断s1对象是否为1个Student对象, 不包括Student的子类对象
    4). 判断类是否为另一个类的子类
    +(BOOL)isSubclassOfClass:(Class)aClass;

11. 构造方法

1. 创建对象
    类名 *指针名 = [类名 new];
    new实际是1个类方法
    new 方法的作用
    ->创建对象
    ->初始化对象
    ->把对象的地址返回
    new 方法的内部,其实是先调用alloc方法, 再调用init方法
    alloc方法是1个类方法, 作用:哪1个类调用这个方法,就创建哪个类的对象, 并把对象返回
    init方法是1个对象方法, 作用:初始化对象
    创建对象的完整步骤:
    应该是先使用alloc创建1个对象, 然后再使用init初始化这个对象,才可以使用这个对象
    虽然没有初始化的对象, 有时候也可以使用, 但是千万不要这么做
    使用1个未经过初始化的对象是极其危险的
    Person *p1 = [Person new];
    完全等价于:
    Person *p1 = [[Person alloc] init];
2. init方法
    作用:初始化对象, 为对象的属性赋初始值, 这个init方法我们叫做构造方法
    init方法做的事情:初始化对象
    为对象的属性赋默认值
    如果属性的类型是基本数据类型就赋值为0
    C指针  为NULL
    OC指针  为nil
    所以,我们创建1个对象如果没有为这个对象的属性赋值, 这个对象的属性是有默认值得
    所以,我们每次新创建1个对象, 这个对象的属性都被初始化了.
3. 我们想要让创建的对象的属性默认值不是nil NULL 0
而是我们自定义的
那么这个时候, 我们就可以重写init方法. 在这个方法中按照我们自己的想法为对象的属性赋值
重写init方法的规范:
    1). 必须要先调用父类的init方法, 然后将方法的返回值赋值给self
    2).调用init方法初始化对象有可能会失败,如果初始化失败,返回的就是nil
    3).判断父类是否初始化成功, 判断self的值是否为nil, 如果不为nil说明初始化成功
    4), 如果初始化成功, 就初始化当前对象的属性
    5).最后, 返回self的值
解惑:
    1).为什么要调用父类的init方法
    因为父类的init方法, 会初始化父类的属性,所以必须要保证当前对象中的父类属性也同时被初始化
    2).为什么要赋值给self?
    因为,要调用父类的init方法, 会返回初始化成功的对象
    实际上返回的就是当前对象, 但是我们要判断是否初始成功
    无论如何, 记住重写init方法的规范
    -(instancetype)init{
        if(self =[super init]){
            //初始化当前类的属性代码;
        }
        return self;
    }
    什么时候需要重写init方法:
    如果你希望创建出来的对象的属性的默认值不是nil NULL 0 而是我们制定的值, 那么这个时候我们就可以重写init方法
3.重写init方法以后
稍稍不爽的:这样每次创建出来的对象的属性的值都是一样的
创建对象的时候, 对象的属性的值由创建对象的人来指定, 而不是写死在init方法中
自定义构造方法:
规范:
1).自定义构造方法的返回值必须是instancetype
2).自定义构造方法的名称必须以initWith开头
3).方法的实现和init的要求一样
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值