鸿蒙开发入门——ArkTS语法简介(万字简介)

news2024/11/23 18:53:20

ArkTS

作为鸿蒙开发的编程语言,我们先来一图看看这个语言,我们可以看到ArkTS是在TS(TypeScript)的基础上改造的,而TS又是在JS(JavaSript)上改造的,一句话总结就是ArkTS是TS的超集,TS是JS的超集。但ArkTS虽然基于TS,但在某些方面可能施加更严格的类型约束,以适应跨端开发的需求
ArkTS
废话不多说,我们紧接着来说语法,在语法上,其与其他编程语言在语法上并没有很本质的不同,毕竟都是高级的开发编程语言,大家都是有各自的特点,但目的都是为了开发软件,我们就仅在语言层面进行总结

语法

变量类型及变量声明方式

基础的变量声明方式
变量声明

基础数据类型

  • number
  • string
  • boolean

复合数据类型

  • Array(容器类型——还有很多其它的容器如)
    let arr = new Array<string>();
    
  • Object(类型)
    let obj:Object = new Stack<number>();
    
    Object 类型是一个所有非原始类型的基类。原始类型包括 string、number、boolean等内置类型,所以Object 类型可以接收所有非原始类型的值,如对象字面量、数组、函数等
    但要注意在默认情况下,ArkTS中所有类型都不允许赋值为null或undefined

其它特殊类型

  • 联合类型
    联合类型即给声明能够接受多种类型的变量,通过竖线(“|”)将不同的类型联合起来,自定义类型也可以联合

    class Cat {
    // ...
    }
    class Dog {
    // ...
    }
    class Frog {
    // ...
    }
    type Animal = Cat | Dog | Frog | number
    // Cat、Dog、Frog是一些类型(类或接口)
    
    let animal: Animal = new Cat();
    animal = new Frog();
    animal = 42;
    // 可以将类型为联合类型的变量赋值为任何组成类型的有效值
    
  • void类型
    一般void类型都是用于作为函数返回值

  • null和undefined

    • null类型主要表示空值,用于明确表示一个变量没有指向任何对象或暂时不知道给什么具体值
    • undefined主要表示一个变量声明了但还未赋值,如在函数使用了可选参数未传递时则该参数的值就为undefined

    总结来说,null是一个明确的“空”值,而undefined表示一个变量或值尚未被定义或赋值。

  • enum类型
    枚举类型即包含一组常量的集合,如

    enum Color {  
      Red,  
      Green,  
      Blue  
    }
    

    定义了该类型后可以在声明类型时使用该类型进行声明,如

    let favoriteColor: Color = Color.Green;  
    console.log(favoriteColor); // 输出:1
    
  • 元组类型(tuple)
    本质也是一个数组,不过是知道元素类型的数组,如:

    let tuple: [string, number, boolean] = ["hello", 42, true];
    

    访问元素时也是通过数组下标进行访问,不过需要注意对应的类型匹配,元组的元素数量和类型必须与定义时一致,否则会导致编译错误。
    tuple实例

补充说明

  • 匿名类型(起别名):type
    Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称
    type int = number;
    let i: int = 1;
    type Matrix = number[][];
    type Handler = (s: string, no: number) => string;
    type Predicate <T> = (x: T) => Boolean;
    type NullableObject = Object | null;
    
  • tips:注意在ArkTS中,类型都必须指明,但在TS中可以使用any关键字接收任意类型的变量,需要注意区分any
  • 空值安全
    上面说过了,默认情况下,ArkTS中的所有类型都是不可为空的,因此类型的值不能为空,当使用的变量为空或者有可能为空时,编译器都会报错,但一些情况下我们也要赋空值或undefined,下面情况说明了如何在ArkTS中能够使用空值和undefined初始化变量
    • 使用非空断言运算符(!):紧接在变量后使用"!",判断变量为空时则不使用该值,不为空时则使用该值
    class C {
      value: number | null = 1;
    }
    
    let c = new C();
    let y: number;
    y = c.value + 1;  // 编译时错误:无法对可空值作做加法
    y = c.value! + 1; // ok,值为2
    // 若c.value为空时则值为1
    
    • 空值合并运算符(??):a ?? b等价于三元运算符(a != null && a != undefined) ? a : b,即如果a为空或undefined时则值等于b,否则值等于a
    • 可选链(后缀运算符?):在访问某个变量时,在其后加个"?“,访问时则会判断其是否为null或undefined,如果是则返回undefined,不是则访问该变量。在一些类中声明变量时在其后加个”?"也表示该变量可为undefined
    // 如果一个Person的实例有不为空的spouse属性,
    // 且spouse有不为空的nick属性,则输出spouse.nick。否则,输出undefined
    class Person {
      nick: string | null = null
      spouse?: Person
    
      constructor(nick: string) {
        this.nick = nick;
        this.spouse = undefined;
      }
    }
    
    let p: Person = new Person('Alice');
    console.log(p.spouse?.nick); // undefined)
    
    p.spouse = p;
    console.log(p.spouse?.nick);
    

其它部分常用语句

此处仅列举与C++有些区别的语句

for

  • 一般的循环:for(let i = 0; i < 10; i+= 2){…}

  • 范围for: for (forVar of expression) {statements}

    forVar: expression的一个元素;expression:一个“容器” 如:

    for (let ch of 'a string object') {/* process ch */}

break

一般正常使用
如果break语句后带有标识符,则将控制流转移到该标识符所包含的语句块之外。如:

let x = 1
label: while (true) {  
	switch (x) {
	    case 1:      // statements      
	    break label // 中断while语句  
	    }
}

函数

函数的声明

函数声明中,函数的返回值类型可以省略
tips:返回值的类型也可以是一个联合类型
函数声明

函数参数

  • 可选参数:name?:type
    此处的name如果未传入则是undefined
    function hello(name?: string) {
    	if (name == undefined) {
    		console.log('Hello!');
    	} else {
    		console.log(`Hello, ${name}!`);
    	}
    }
    
  • 可选参数的另一种形式(默认参数)
    function multiply(n: number, coeff: number = 2): number {
    	return n * coeff;
    }
    multiply(2);  // 返回22
    multiply(2, 3); // 返回23
    
  • Rest参数(可变长参数)
    后面的数组类型是什么,则只能接收什么类型的参数
    function sum(...numbers: number[]): number {
      let res = 0;
      for (let n of numbers)
        res += n;
      return res;
    }
    
    sum() // 返回0
    sum(1, 2, 3) // 返回6
    // 使用Object类型时的数组,可传入多种不同类型的参数,都会保存到给的数组里
    function exampleFunction(...args: Object[]) {
      args.forEach(arg => {
        console.log(arg.toString());
      });
    }
    
    exampleFunction(1, 'string', true);
    

函数类型——箭头函数(lambda表达式)

lambda表达式

语法:(参数列表):返回值=>{函数体}
我们可以将函数类型保存:type trigFunc = (x: number) => number // 这是一个函数类型
lambda的返回值可省略,返回值省略时根据函数体推导返回值,函数体仅一行时可以去掉大括号,所以指向类型为number时说明返回值的类型是number,代码含义即为一个函数类型为参数是一个number类型,返回值为number类型的函数

函数闭包

即在函数体内部又包含一个函数,那么这个函数从声明到内部这包含的另一个函数之间的作用域的变量会被保存下来(类似变成了局部全局)

function f(): () => number {
  let count = 0;
  let g = (): number => { count++; return count; };
  return g;
}

let z = f();
z(); // 返回:1
z(); // 返回:2

函数重载

函数重载(重载方式与其它语言不完全相同,实现只能有一个,定义可以重载多个,即签名。注意这里的参数也可以使用联合类型)

function foo(x: number): void;            /* 第一个函数定义 */
function foo(x: string): void;            /* 第二个函数定义 */
function foo(x: number | string): void {  /* 函数实现 */
}

foo(123);     //  使用第一个定义
foo('aa'); // 使用第二个定义

类的基本操作都与C++相似,通过上面的变量、函数的内容即可封装一个类,下面主要介绍一些不同的地方

关于封装

ArkTS中,要求所有成员必须在声明时就进行定义初始化(或在构造函数中进行初始化),即所有字段在声明时或者构造函数中显式初始化
但也可以通过可选链的方式表示为undefined,但此时使用值时则需要对应注意
封装的说明

getter和setter

在类内实现getter和setter时,首先可以使用deveco一键生成
我们要关注一点的是此处生成的函数形式是get/set 属性(): 返回类型{return 返回值} 而不是一般的声明函数的方式,如:

class Person {
  name: string = ''
  private _age: number = 0
  get age(): number { return this._age; }
  set age(x: number) {
    if (x < 0) {
      throw Error('Invalid age argument');
    }
    this._age = x;
  }
}

let p = new Person();
p.age; // 输出0
p.age = -42; // 设置无效age值会抛出错误

构造函数

构造函数在实现上与其他语言也大体相似,未提供构造时默认会自动创建具有空参数列表的默认构造函数
但需要注意的是,构造函数也可以重载多个形式,但与函数重载相同,重载时实现在类中只能有一个,重载定义可以有多个,如:

class C {
  constructor(x: number)             /* 第一个签名 */
  constructor(x: string)             /* 第二个签名 */
  constructor(x: number | string) {  /* 实现签名 */
  }
}
let c1 = new C(123);      // OK,使用第一个签名

let c2 = new C('abc');    // OK,使用第二个签名
// 以下方式则是错误的
class A{
  constructor(x: number) {
  }
  constructor(x: string) {
  }
}

关于类的实例创建

  • 类都是使用new进行实例的创建
    可以直接使用构造函数构建实例对象

    let p = new Person('John', 'Smith');
    console.log(p.fullName());
    
    class Point {
      x: number = 0
      y: number = 0
    }
    let p: Point = {x: 42, y: 42};
    
  • 静态字段:使用static声明变量即可(而不是用let或const)

  • 继承
    继承时,父类中受访问限定符成员也会相同继承到子类

    • 使用extends进行继承,只能继承一个类
      但可以通过继承接口来继承多个接口,使用implements
      • 一个类,可以同时继承某一个类之后再继承多个接口
      • 继承接口时,必须实现接口内定义的所有方法(除非接口内的方法已有默认实现)
    • 在子类中,父类通过super进行访问,super即代表了父类的实例
      • 在继承类了父类的子类中,构造函数第一行必须通过super(…)显式的调用父类的构造函数,当然如果不提供构造函数,会使用默认生成的构造函数,其会自动去调用父类的构造函数
    • 关于继承后的方法重写
      • 重写本质是为了形成多态
      • 重写时需要与被重写的方法具有相同的方法名、参数类型与返回类型
    • 类中的重载——本质也和arkts的函数重载相同,只能重载定义(建立签名),实现只能有一个。重载的函数的名称和参数列表不能均相同
  • 多态在继承后直接重写同名函数即可

  • 类的创建

    • 直接使用new创建对象
    • 关于对象字面量:封闭在花括号对({})中的’属性名:值’的列表。
      • 使用{…}(对象字面量)创建,内部的参数为类内的成员(按照顺序进行初始化)
        但是要确保对象字面量的结构符合类的结构,但并没有创建类的实例。

      • 对象字面量只能可以推导出该字面量类型的上下文中使用。其他正确的例子:

        class C {
          n: number = 0
          s: string = ''
        }
        
        let c: C = {n: 42, s: 'foo'};
        
        // 若类C为下述方式,则无法保证对应的对象字面量是C类的实例
        class C {
          a: number = 0;
          b: string = '';
        
          constructor(a: number, b : string) {
          }
        }
        
  • Record类型(就是哈希表的一种,但该语言中也有Map类型)
    let hash = new Map<Number, string>();//哈希表类型

    泛型Record<K, V>用于将类型(键类型)的属性映射到另一个类型(值类型)

    • Key只能是字符串或数值类型,但Value可以是任意类型

    tips:使用时需要先进行初始化

    // 创建一个哈希表
    let hashTable: NumberStringHashTable = {};
    // 访问和修改哈希表中的值
    console.log(hashTable[1]); 
    // 输出: onehashTable[1] = 'ONE';
    console.log(hashTable[1]); // 输出: ONE
    // 添加新的键值对
    hashTable[4] = 'four';
    // 遍历哈希表
    Object.keys(hashTable).forEach(key => {\
      console.log(`${key} = ${hashTable[key]}`);
    

接口

  • 接口的声明
    • 使用interface关键字
    • 接口可以继承其他接口,其他类继承可以继承多个接口(implements)
    • 接口中的函数声明可以不使用(省略掉)function关键字

泛型编程(模板)

用于定义模板类、模板接口以及模板函数等,直接用尖括号表示即可

  • 模板类和接口

    class CustomStack<Element> {
      public push(e: Element):void {
        // ...
      }
    }
    // 要使用类型CustomStack,必须为每个类型参数指定类型实参
    let s = new CustomStack<string>();
    s.push('hello');
    // 在使用泛型类型和函数时会确保类型安全
    s.push(55); // 将会产生编译时错误
    
  • 泛型类型的类型参数可以绑定.例如,HashMap<Key, Value>容器中的Key类型参数必须具有哈希方法,即它应该是可哈希的。

    即通过继承接口的方式,使得对应的泛型参数(类型)在传递过来时必须实现对应的接口,
    Key 类型参数被约束为 Hashable 接口的实现。这意味着只有那些实现了 hash 方法的类型才能用作这个哈希映射的键。

    interface Hashable {
      hash(): number
    }
    class HasMap<Key extends Hashable, Value> {
      public set(k: Key, v: Value) {
        let h = k.hash();
        // ...其他代码...
      }
    }
    
  • 泛型函数

    语法:function last<T>(x: T): T

    在函数名后加上尖括号,之后即可在参数列表、返回类型以及函数体中使用对应的模板参数

    返回数组最后一个元素的函数

    function last(x: number[]): number {
      return x[x.length - 1];
    }
    last([1, 2, 3]); // 3
    // 模板函数:
    function last<T>(x: T[]): T {
      return x[x.length - 1];
    }
    
  • 泛型的默认值

    在泛型的类型参数可以设置默认值,此时使用时则可以不指定泛型的形参而直接使用泛型类型的名称,如下

    class SomeType {}
    interface Interface <T1 = SomeType> { }
    class Base <T2 = SomeType> { }
    class Derived1 extends Base implements Interface { }
    // Derived1在语义上等价于Derived2
    class Derived2 extends Base<SomeType> implements Interface<SomeType> { }
    
    function foo<T = number>(): T {
      // ...
    }
    foo();
    // 此函数在语义上等价于下面的调用
    foo<number>();
    

模块

常见的为ets文件中的模块的导入与导出

模块即可以理解是一个作用域,小到函数体、类,大到文件等,每个模块都有自己的作用域,该模块之外都不可见,除非被显式导出

与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中

  • 导出(类、变量、函数都可导出)

    • 通过export关键字导出
    • 未导出的声明名称被视为私有名称,只能在声明该名称的模块中使用(没导出就不能四处用)

    注意:通过export方式导出,在导入时要加{}。

    export class Point {
      x: number = 0
      y: number = 0
      constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
      }
    }
    export let Origin = new Point(0, 0);
    export function Distance(p1: Point, p2: Point): number {
      return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
    }
    
  • 导入

    • 静态导入

      即直接使用导入声明对想要的模块直接先进行导入,导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定。导入声明由两部分组成:

      • 导入路径,用于指定导入的模块;
      • 导入绑定,用于定义导入的模块中的可用实体集和使用形式(限定或不限定使用)
      • 导入形式
        1. 直接导入,并且绑定名称

          import * as Utils from './utils'
          Utils.X // 表示来自Utils的X
          Utils.Y // 表示来自Utils的Y
          
        2. 绑定对应的导入实体名称

          import { X, Y } from './utils'
          X // 表示来自utils的X
          Y // 表示来自utils的Y
          
        3. 给绑定的导入实体起别名

          import { X as Z, Y } from './utils'
          Z // 表示来自Utils的X
          Y // 表示来自Utils的Y
          X // 编译时错误:'X'不可见
          
    • 动态导入(后续再进行详解)

      动态导入即是根据条件导入模块(或按需导入),使用import()语法实现

      import()语法通常称为动态导入dynamic import,是一种类似函数的表达式,用来动态导入模块。以这种方式调用,将返回一个promise。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1936802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为 android编译 luajit库、 交叉编译

时间&#xff1a;20200719 本机环境&#xff1a;iMac2017 macOS11.4 参考: 官方的文档&#xff1a;Use the NDK with other build systems 写在前边&#xff1a;交叉编译跟普通编译类似&#xff0c;无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Make…

鸿蒙 next 5.0 版本页面跳转传参 接受参数 ,,接受的时候 要先定义接受参数的类型, 代码可以直接CV使用 [教程]

1, 先看效果 2, 先准备好两个页面 index 页面 传递参数 import router from ohos.routerEntry Component struct Index {Statelist: string[] [星期一, 星期二,星期三, 星期四,星期五]StateactiveIndex: number 0build() {Row() {Column({ space: 10 }) {ForEach(this.list,…

笔记 3 : 继续彭老师课本第 3 章的 arm 的汇编指令

&#xff08;26&#xff09; 指令 LDR &#xff1a; &#xff08;27&#xff09; STR &#xff1a; 可见&#xff0c;从语法上将&#xff0c; &#xff01; 提示编译器进行更复杂的编译&#xff0c;对应内涵更复杂的指令。 &#xff08;28&#xff09; LDR 与 STR 指令还可…

【银河麒麟服务器操作系统】java进程oom现象分析及处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问麒麟软件产品专区&#xff1a;https://product.kylinos.cn 现象描述 某服务器系统升级内核至4.19.90-25.22.v2101版本后仍会触发oom导致java进程被kill。 现象分析 oom现象分析 系统messages日志分析&#xff0c;故…

pikachu之暴力破解

1基于表单的暴力破解 随便输入然后抓包 选中添加账号密码 添加分别添加payload1&#xff0c;2&#xff0c;的字典 开始攻击 2验证码绕过on server 和基于表单的暴力破解相比&#xff0c;多了一个验证码功能 这个验证码是前端的验证码&#xff08;和前面那个一样选中添加账号密码…

计算机网络入门 -- 常用网络协议

计算机网络入门 – 常用网络协议 1.分类 1.1 模型回顾 计算机网络细分可以划为七层模型&#xff0c;分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。而上三层可以划为应用层中。 1.2 分类 1.2.1 应用层 为用户的应用进程提供网络通信服务&#xff0…

第一百七十三节 Java IO教程 - Java缓冲区读写

Java IO教程 - Java缓冲区读写 缓冲区读取 有两种方法从缓冲区读取数据: 绝对位置相对位置 使用四个版本重载的get()方法用于从缓冲区读取数据。 get(int index)返回给定索引处的数据。 get()从缓冲区中的当前位置返回数据&#xff0c;并将位置增加1。 get(byte [] dest…

vmware配置centos+配置静态ip联网+更换镜像

centos7配置参考【实战】VMware17虚拟机以及Centos7详细安装教程-CSDN博客 ip配置步骤&#xff1a; 先更改编辑虚拟网络编辑器中的内容 就按照还原默认设置来&#xff0c;设定后就是以上内容&#xff0c;然后一定要记住子网ip和子网掩码 接下来就是NAT设置&#xff1a; 网关…

Spring Boot集成SFTP快速入门Demo

1.什么是SFTP&#xff1f; SFTP&#xff08;SSH File Transfer Protocol&#xff0c;也称 Secret File Transfer Protocol&#xff09;&#xff0c;是一种基于SSH&#xff08;安全外壳&#xff09;的安全的文件传输协议。使用SFTP协议可以在文件传输过程中提供一种安全的加密算…

ABAP打印WORD的解决方案

客户要求按照固定格式输出到WORD模板中&#xff0c;目前OLE和DOI研究了均不太适合用于这种需求。 cl_docx_document类可以将WORD转化为XML文件&#xff0c;利用替换字符串方法将文档内容进行填充同 时不破坏WORD现有格式。 首先需要将WORD的单元格用各种预定义的字符进行填充…

Redis的AOF持久化策略(AOF的工作流程、AOF的重写流程,操作演示、注意事项等)

文章目录 缓冲AOF 策略(append only file)AOF 的工作流程AOF 缓冲区策略AOF 的重写机制重写完的AOF文件为什么可以变小&#xff1f;AOF 重写流程 缓冲AOF 策略(append only file) AOF 的核心思路是 “实时备份“&#xff0c;只要我添加了新的数据或者更新了新的数据&#xff0…

价格较低,功能最强?OpenAI 推出 GPT-4o mini,一个更小、更便宜的人工智能模型

OpenAI美东时间周四推出“GPT-4o mini”&#xff0c;入局“小而精”AI模型竞争&#xff0c;称这款新模型是“功能最强、成本偏低的模型”&#xff0c;计划今后整合图像、视频、音频到这个模型中。 OpenAI表示&#xff0c;GPT-4o mini 相较于 OpenAI 目前最先进的 AI 模型更加便…

FairGuard游戏加固入选《嘶吼2024网络安全产业图谱》

2024年7月16日&#xff0c;国内网络安全专业媒体——嘶吼安全产业研究院正式发布《嘶吼2024网络安全产业图谱》(以下简称“产业图谱”)。 本次发布的产业图谱&#xff0c;共涉及七大类别&#xff0c;127个细分领域。全面展现了网络安全产业的构成和重要组成部分&#xff0c;探…

微软发布iOS/安卓正式版Designer应用,AI修图功能助力创意设计

一、Microsoft Designer应用正式上线 AITOP100平台获悉&#xff0c;微软一直致力于为用户提供优质的创意工具&#xff0c;此次推出的Microsoft Designer应用正是其在移动端的重要布局。这款应用已正式上线iOS、Android、Windows和网页版本&#xff0c;满足不同用户的需求。微软…

Stable Diffusion 使用详解(2)---- 图生图原理,操作,参数

目录 背景 图生图原理 基本原理 1. 扩散模型基础 2. 图生图的具体流程 3. 关键技术点 4. 应用实例 CLIP 原理 1.基本概念 2. 核心特点 使用及参数 随机种子 重绘幅度 图像宽高 采样方法 1. DPM&#xff08;扩散概率模型&#xff09; 2. SDE&#xff08;随机微…

大语言模型-检索测评指标

1. MRR &#xff08;Mean Reciprocal Rank&#xff09;平均倒数排名&#xff1a; 衡量检索结果排序质量的指标。 计算方式&#xff1a; 对于每个查询&#xff0c;计算被正确检索的文档的最高排名的倒数的平均值&#xff0c;再对所有查询的平均值取均值。 意义&#xff1a; 衡量…

ChatTTS超强的真人AI语音助手下载使用教程

简介 ChatTTS是专门为对话场景设计的文本转语音模型&#xff0c;支持多人同时对话&#xff0c;适用的场景非常丰富&#xff0c;比如LLM助手对话任务&#xff0c;视频配音、声音克隆等。同时支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练&#xf…

【Android】 dp与sp,加冕为王

目录 重要概念 屏幕尺寸 屏幕分辨率 屏幕像素密度 基础知识&#xff1a; ppi pt DPI 的定义和重要性 Android 中的 DPI 级别 px dp&#xff08;Density Independent Pixels&#xff09; sp&#xff08;Scale-independent Pixels&#xff09; 安卓的dp/dip、sp 虚拟…

设置浏览器网页全屏

在日常笔记本上办公时&#xff0c;由于屏幕较小&#xff0c;为了尽可能多和方便的显示浏览器网页上的内容&#xff0c;可以设置网页全屏的方式&#xff0c;去掉屏幕顶端的网址栏和底端栏&#xff0c;具体设置如下&#xff1a; 以Edge浏览器和Google Chrome浏览器为例&#xff…

如何免费用java c#实现手机在网状态查询

今天分享手机在网状态查询接口&#xff0c;该接口适用的场景非常广泛&#xff01;首先我们先讲下什么是手机在网状态&#xff1f;简单来说&#xff0c;就是你得手机号是否还在正常使用中&#xff0c;是否能够及时接收和回复信息&#xff0c;是否能够随时接听和拨打电话。如果你…