百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Android必备之Kotlin入门(1):基础知识

wptr33 2024-12-03 18:45 12 浏览

1:摘要

Kotlin是JetBrains公司开发与设计的一款编程语言,其第一个版本在2011年被公布,并在2012年被开源,2017年Google宣布kotlin正式成为Android开发的第一语言。事实上,熟练地使用kotlin可以大大提高开发效率。关于Kotlin的知识,我将会用两篇文章来介绍,第一篇介绍Kotlin相关的基础知识,第二篇文章介绍Kotlin的一些高级特性,我将尽可能用简单易懂的表达方式向大家介绍相关知识点,欢迎大家关注。

2:为什么可以使用kotlin开发Android应用?

我们知道Android是Google家的产品,那么JetBrains作为一家第三方公司,其开发的kotlin为什么有支持Android的能力?

想要回答这个问题,我们需要从程序的运行的机制来分析。

编程语言分为两大类:

  • 编译型语言:编译器先将代码编译为计算机可以识别的二进制文件,然后直接执行二进制文件
  • 解释型语言:解释器在程序运行时实时读取代码并将其解释成计算机可以理解的二进制数据进而执行

那么Android原本的开发语言Java属于哪类语言呢?有的同学可能会说因为Java是先编译(javac命令)后运行的,所以Java是编译型语言,而有的熟悉JVM的同学又会说因为JVM中有解释器的存在,所以是解释型语言。正确答案是后者,那么如何解释前者中Java的编译过程呢?不错,Java代码在执行之前确实需要编译,这也是为什么会有javac命令存在的原因,但是其编译的产物并不是计算机可以直接识别的二进制文件,而是一种特殊的class文件,在运行时Java虚拟机(Android中的ART)会对class文件进行实时识别,然后实时执行,所以Java属于解释型语言。

我们再来回到最初的问题:kotlin为什么有支持Android的能力?

答案很简单,既然Android可以识别Java编译的class文件从而运行java程序,那么只要kotlin保证自己编译的产物也是和Java一样的class文件即可,事实上kotlin也是这么做的,也就是说,对Android的ART来说,kotlin和java并没有任何区别,因为其只关心class文件是什么,至于class文件是由哪一门程序语言编译产生的并不关心,这也就解释了为什么可以使用kotlin开发Android应用程序。

了解了kotlin的大致原理后,我们就来具体学习kotlin这门语言,首先从最基础的变量和函数学起。

3:变量和函数

3.1:变量

kotlin中的声明变量有两个关键字:

  • val,value的缩写,表示“不可变”变量,该类型的变量在被赋值后不能再改变,相当于Java中给变量加上了final关键字
  • var,variable的缩写,表示“可变”变量,该类型的变量在被赋值后可以继续被赋予新值

比如:

fun main(){
    val x=10
    var y=20
    x=20
    y=30
}

编译器会报错:

提示val类型的变量不可被重新赋值。

大家可能会发现,我上面写的代码没有声明x和y的类型,但是程序照样可以正常运行,这是因为kotlin有强大的类型推导机制,也就是说,因为它看到你给x赋值10,而10是一个整型,所以它认为x就是一个整型,所以:

val x=10

相当于Java中的:

final int x=10

那如果我想指定某个变量的值呢?语法是:

val x:Int=10

即使用 :来指定遍历的类型,同时也可以看到,kotlin中的整型值Int而不是java中的int,因为kotlin完全摒弃了Java中的基本数据类型,所有的数据类型都是对象,具体Java与Kotlin数据类型关系如下表所示:

可能有的读者会有疑问,既然kotlin中有val和var两种类型的变量,那在实际编程中如何判断一个变量应该用val修饰还是var修饰?首先我们应该明确,越不可变的变量其稳定性越高,因为你可以很明确地知道它的值,它不会被其他人改变,如果出现问题,你可以首先排除是它的问题,所以,好的编程习惯是尽量保证变量不可变,即对一个新变量的声明,如果可以用val,尽量用val,除非val不能满足你的实际需求,再用var,这样可以保证你的程序尽可能地健壮。

3.2:函数

函数是运行代码的载体,一个函数中可以写多行代码、实现复杂的逻辑,函数运行时会依次运行函数的代码,kotlin中函数的声明方法如下:

可以看到,一个函数主要由5部分构成:

  1. fun,是定义函数的关键字
  2. 函数名
  3. 参数,格式为 参数名:参数类型
  4. 返回值类型,表示该函数的返回值类型
  5. 函数体,该函数具体的逻辑

另外,在kotlin中还有一个语法糖,在日常开发中会经常用到:当一个函数的函数体中只有一行代码时,可以不必编写函数体,可以直接用等号函数定义和这一行代码连接起来即可,比如:

fun functionName(param1: Int, param2: String): Int = 0

4:程序的控制逻辑

程序的执行语句主要有三种:顺序语句、条件语句、循环语句。顺序语句很简单,按照想要的顺序一行一行写代码即可,这里主要介绍条件语句和循环语句。

4.1:条件语句

kotlin中条件语句主要有两种实现方式:if和when。

4.1.1:if

比如我们要写一个找出两个数中较大的数并将其返回的函数,使用kotlin的if语句可以这样写:

fun getTheLargerOne(num1: Int, num2: Int): Int {
  var largerOne=0 
  if (num1 > num2) {
      largerOne=num1
  } else {
      largerOne=num2
  }

return largerOne
}

逻辑很好理解,不做过多赘述,从这个函数看,kotlin中的if和Java中的if没什么区别,但是事实上kotlin中的if相比于java中的if多了一个“具有返回值”的特性,即kotlin中的if会返回if语句中最后一行代码的返回值。所以,上述代码可以简化为:

fun getTheLargerOne(num1: Int, num2: Int): Int {
  var largerOne=if (num1 > num2) {
      num1
  } else {
      num2
  }
  return largerOne
}

进一步简化,我们可以去掉largerOne这个变量的引入:

fun getTheLargerOne(num1: Int, num2: Int): Int {
  return  if (num1 > num2) {
      num1
  } else {
      num2
  }
}

这时代码已经很简洁了,但是想想我们在介绍函数的时候,介绍过一个语法糖:当一个函数的函数体中只有一行代码时,可以不必编写函数体,可以直接用等号函数定义和这一行代码连接起来即可。所以,我们可以继续将程序简化为:

fun getTheLargerOne(num1: Int, num2: Int) = if (num1 > num2) num1 else num2

怎么样,现在的程序是不是比简化之前的版本更加简洁。

4.1.2:when

when语句类似Java中的switch,但是比switch更加强大。Java中的switch只能传入整型或短于整型的变量作为条件(JDK1.7之后增加了对字符串变量的支持),所以适用范围很窄,另外switch的每一个case最后都要手动加上break,否则会继续执行下一个case,这个特性既繁琐又极易引出bug。kotlin中的when完美解决了上述switch的痛点,而且还增加了很多新特性。我们来以一个例子说明when的用法,输入一个学生的姓名,输出他的成绩,用if来写的话应该是这样:

fun getScore(name: String) = if (name == "张三") 70 else if (name == "李四") 80 else if (name == "小明") 90 else 60

可以看到,当判断条件比较多的时候使用if就显得代码很繁琐,这时候就可以使用when来优化:

fun getScore(name: String) = when (name) {
  "张三" -> 70
  "李四" -> 80
  "小明" -> 90
  else -> 60
}

可以看到,使用when优化之后的代码简洁了很多,另外,从代码你应该也看出来了,when和if一样,可以有返回值,返回值也是执行的最后一行代码。when语句允许传入一个任意类型的参数,然后可以在when的结构体中定义一系列的条件,格式为:

匹配值->{逻辑}

当逻辑只有一行的时候可以省略{},上面的例子就是省略{}的结果。另外,when还有一种不带参数的用法,比如我们想要实现所有姓薛的人分数都是100分,使用带参数的when可能需要:

fun getScore(name: String) = when (name) {
  "薛之谦" -> 100
  "学狗蛋" -> 100
  "薛爱国" -> 100
  "张三" -> 70
  "李四" -> 80
  "小明" -> 90
  else -> 60
}

我们可以使用不带参数的when来实现相同的逻辑:

fun getScore(name: String) = when {
  name.startsWith("薛") -> 100
  name == "张三" -> 70
  name == "李四" -> 80
  name == "小明" -> 90
  else -> 60
}

4.2:循环语句

kotlin中提供了两种循环,一种是while,另一种是for,while的用法和特性与java一样,所以不做过多介绍,这里主要介绍一下kotlin中for循环的用法。kotlin中的for循环主要是for-in,在介绍for-in之前我们先来介绍一下区间的概念。kotlin中区间的声明格式如下:

val range=1..10

这时range=[1,2,3,4,5,6,7,8,9,10],即kotlin使用..来创建一个区间,且区间的两端都是闭区间的。那如果想创建一个开区间的区间呢?kotlin给我们提供了until关键字:

val range=1 until 10

这时range=[1,2,3,4,5,6,7,8,9],即until代表的区间为”左闭右开“。现在我们可以用for来遍历区间:

for(i in 1..10){
      println(i)
}

或者:

for (i in 1 until 10){
      println(i)
}

那么如果想要每次遍历时i加2怎么办?kotlin给我们提供了step关键字:

for(i in 1..10 step 2){
      println(i)
}

以上区间都是值增的区间,那么值减的区间如何声明呢?kotlin给我们提供了downTo关键字,用法如下:

for (i in 5 downTo 1){
      println(i)
}

需要注意的是这里的downTo是闭区间,即5 downTo 1代表[5,4,3,2,1],同时,downTo也可以配合step使用。

5:面向对象

5.1:类与对象

kotlin中类的声明方法为:

class Animal{
    var gender=""
    var age=0
    
    fun eat(){
        println("$gender is eating")
    }
}

上门的代码定义了一个Animal动物类,其有两个属性,一个是gender性别,另一个是age年龄,此外还声明了一个eat方法,代表动物在吃东西。

现在我们可以实例化一个Animal类的对象:

val animal=Animal()

可以看到,kotlin实例化对象的时候不需要像Java那样使用new关键字,直接调用类的构造函数即可。

5.2:继承与构造函数

面向对象编程势必要引入继承,我们举一个例子,我们想构造一个Cat猫类,其继承自Animal动物类,那么首先,我们需要使Animal类变成可被继承的类,在Kotlin中,不是所有类都可以被继承,这也是其与Java比较大的一个区别,kotlin中任何一个非抽象类默认都是不可以被继承的,相当于Java中给类声明了final关键字,注意这里说的是”默认“情况下不可被继承,这是因为Kotlin在设计的时候认为类和变量一样,都应该尽量不被改变,以此保证安全性,那么如何让一个非抽象类变成可被继承的呢?kotlin给我们提供了open关键字,只需要在类前面加上open关键字即可,这样相当于告诉kotlin,我需要让这个类被继承,比如:

open class Animal{
    var gender=""
    var age=0

    fun eat(){
        println("$gender is $age years old")
    }
}

现在我们就可以创建继承自Animal的Cat类了:

class Cat:Animal(){
    val suit=""
}

可以看到,kotlin中是通过:来声明继承关系的,可能会有读者对这里的Animal后面的括号有疑惑,为什么需要带这个括号呢?一定要带吗?这个涉及到kotlin中构造函数的相关知识。

kotlin中将构造函数分为两类:

  • 主构造函数
  • 次构造函数

每个类默认有一个不带参数的主构造函数(也可以手动给其添加参数),主构造函数没有函数体,比如:

class Animal{
    var gender=""
    var age=0
    
    fun eat(){
        println("$gender is eating")
    }
}

就相当于:

class Animal(){
    var gender=""
    var age=0
    
    fun eat(){
        println("$gender is eating")
    }
}

因为这里主构造函数没有参数,所以可以把()省略,如果想要给其添加参数,可以:

class Animal(var category:String){
    var gender=""
    var age=0

    fun eat(){
        println("$gender is $age years old")
    }
}

可能有的同学就有疑惑了,这个主构造函数没有函数体,那如果想在对象初始化时执行一些代码该怎么办呢?kotlin给我们提供了一个init构造体,所有想要安排在主构造函数的逻辑都可以写在里面:

class Animal(var category:String){
    
    init {
        println("Animal被实例化")
    }
    var gender=""
    var age=0

    fun eat(){
        println("$gender is $age years old")
    }
}

现在我们就可以解释为什么:

class Cat:Animal(){
    val suit=""
}

中Animal()需要带上括号,因为根据继承特性规定,子类需要在构造函数中调用父类的构造函数的,但是我们说kotlin中主构造函数是没有函数体的,那么子类在哪调用父类的构造函数呢?kotlin给出的答案是通过括号来调用,即class Cat:Animal()中,()表示执行Cat的主构造函数时调用父类Animal的主构造函数,所以,就算()中没有参数,也不可以省略。

以上介绍了主构造函数,下面我们来介绍次构造函数。

任何一个类最多只能有一个主构造函数,但是可以有多个次构造函数,次构造函数也可以被用来实例化对象,其是有函数体的,比如:

class Animal(var category: String) {

    constructor(category: String, vision: String) : this(category) {
        println("这是次构造函数")
    }

    init {
        println("Animal被实例化")
    }

    var gender = ""
    var age = 0

    fun eat() {
        println("$gender is $age years old")
    }
}

可以看到,kotlin中使用constructor声明次构造函数,并且kotlin规定当一个类既有主构造函数又有次构造函数时,次构造函数必须调用主构造函数,如上面的this(category)。

还有一种情况是一个类没有主构造函数,但是有次构造函数,比如:

class Cat : Animal {
    constructor(category: String, vision: String) : super(category, vision) {
        
    }

    val suit = ""
}

可以看到,首先Cat类没有声明主构造函数,其次,Cat声明了次构造函数,所以Cat是一个没有主构造函数但是有次构造函数的类,既然Cat没有主构造函数,其主构造函数也就不会被执行,所以其就不用规定执行其主构造函数时必须执行父类的构造函数了,所以继承Animal的时候就可以把()去掉,但是在声明Cat的次构造函数的时候,必须通过super调用父类的构造函数。

其实在实践编程时,次构造函数是很少用到的,什么原因呢?想想我们为什么需要次构造函数?当然是为了多一种实例化的方式,比如主构造函数只声明了接收一个参数,现在新需求想要加一个有两个参数的构造函数,所以想到加一个次构造函数来解决问题,kotlin为了解决这个痛点,引入了对参数默认值的支持,比如:

open class Animal(var age:Int) {
    
    constructor(category: String, vision: String):this(10) {
    }
    
}

可以改造为:

open class Animal(var age: Int = 10, category: String, vision: String) {

}

这时我们可以用两种方式实例化Animal的对象:

val a1 = Animal(category = "", vision = "")
val a2 = Animal(age = 20, category = "", vision = "")

5.3:接口

kotlin和java一样,一个类只能最多继承一个类,但是可以实现多个接口,kotlin声明接口的方法如下:

interface Eat {
    fun openMouth()
    fun closeMouth()
}

可以看到,kotlin使用interface声明接口,并且声明了openMouth和closeMouth两个函数,现在我们就可以让Cat类实现该接口了:

class Cat : Animal,Eat {
    override fun openMouth() {
    }
    override fun closeMouth() {
    }
    constructor(category: String, vision: String) : super(category, vision) {
    }
    val suit = ""
}

可以看到,kotlin中实现和继承都是通过:实现的,只需要用,将父类、接口隔开即可。同时,kotlin允许接口中的函数有默认实现,比如:

interface Eat {
    fun openMouth()
    fun closeMouth() {
        println("closeMouth")
    }
}

这时实现Eat时只会强制要求实现openMouth()函数,不会强制要求实现closeMouth() 函数。

5.4:可见性修饰符

Java有public、protected、private、default四种可见性修饰符,kotlin中也有四种,分别是public、private、protected、internal,其可见性对比见下表:


这里internal的可见性为同一模块中可见,其应用场景是,比如我们开发了一个模块给别人用,我们希望某个方法只可以被我们本模块自己用,不开放给用户,就可以将其声明为internal。

5.5:数据类与单例类

5.5.1:数据类

什么是数据类?我们所说的MVC、MVP、MVVM等架构模式,其中的M指的就是数据类,那我们一般是如何定义数据类的呢?回想一下Java中数据类的定义方法,这里举个例子:

public class Animal {
    int age;
    String gender;
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Animal) {
            Animal animal = (Animal) obj;
            if (animal.age == this.age && animal.gender == this.gender) {
                return true;
            }
            return false
        }
        return false;
    }
    @Override
    public int hashCode() {
        return gender.hashCode() + age;
    }
    @Override
    public String toString() {
        return "age is:" + age + "gender is:" + gender;
    }
}

可以看到,Java中定义一个数据类通常需要重写equals()、hashCode()、toString()这几个方法,其用途分别为:

  • equals():判断两个数据类是否相等
  • hashCode():为了保证HashMap、HashSet等数据结构可以正常工作
  • toString():为了提供更清晰的日志

可以看到,Java中实现一个数据类步骤很繁琐,需要写很多没有实际逻辑意义的代码,所以kotlin对此进行了优化,在kotlin中声明一个数据类只需要:data class Animal(val age: Int, val gender: String) 可以看到,只需要在声明类之前加上data关键字,就可以将一个类声明为数据类,kotlin会自动根据主构造函数中的参数帮你将equals()、hashCode()、toString()等固定写法的方法自动生成,我们将上面这行代码的字节码反编译为java代码,可以得到如下结果:

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Metadata(
   mv = {1, 1, 13},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u000e\n\u0002\b\t\n\u0002\u0010\u000b\n\u0002\b\u0004\b\u0086\b\u0018\u00002\u00020\u0001B\u0015\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005¢\u0006\u0002\u0010\u0006J\t\u0010\u000b\u001a\u00020\u0003H?\u0003J\t\u0010\f\u001a\u00020\u0005H?\u0003J\u001d\u0010\r\u001a\u00020\u00002\b\b\u0002\u0010\u0002\u001a\u00020\u00032\b\b\u0002\u0010\u0004\u001a\u00020\u0005H?\u0001J\u0013\u0010\u000e\u001a\u00020\u000f2\b\u0010\u0010\u001a\u0004\u0018\u00010\u0001H?\u0003J\t\u0010\u0011\u001a\u00020\u0003H?\u0001J\t\u0010\u0012\u001a\u00020\u0005H?\u0001R\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\u0007\u0010\bR\u0011\u0010\u0004\u001a\u00020\u0005¢\u0006\b\n\u0000\u001a\u0004\b\t\u0010\n¨\u0006\u0013"},
   d2 = {"LAnimal;", "", "age", "", "gender", "", "(ILjava/lang/String;)V", "getAge", "()I", "getGender", "()Ljava/lang/String;", "component1", "component2", "copy", "equals", "", "other", "hashCode", "toString", "LearnKotlin"}
)
public final class Animal {
   private final int age;
   @NotNull
   private final String gender;

   public final int getAge() {
      return this.age;
   }

   @NotNull
   public final String getGender() {
      return this.gender;
   }

   public Animal(int age, @NotNull String gender) {
      Intrinsics.checkParameterIsNotNull(gender, "gender");
      super();
      this.age = age;
      this.gender = gender;
   }

   public final int component1() {
      return this.age;
   }

   @NotNull
   public final String component2() {
      return this.gender;
   }

   @NotNull
   public final Animal copy(int age, @NotNull String gender) {
      Intrinsics.checkParameterIsNotNull(gender, "gender");
      return new Animal(age, gender);
   }

   // $FF: synthetic method
   @NotNull
   public static Animal copy$default(Animal var0, int var1, String var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.age;
      }

      if ((var3 & 2) != 0) {
         var2 = var0.gender;
      }

      return var0.copy(var1, var2);
   }

   @NotNull
   public String toString() {
      return "Animal(age=" + this.age + ", gender=" + this.gender + ")";
   }

   public int hashCode() {
      int var10000 = this.age * 31;
      String var10001 = this.gender;
      return var10000 + (var10001 != null ? var10001.hashCode() : 0);
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof Animal) {
            Animal var2 = (Animal)var1;
            if (this.age == var2.age && Intrinsics.areEqual(this.gender, var2.gender)) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}

可以看到,kotlin在编译的时候帮我们自动完成了equals()、hashCode()、toString()等函数,为我们减少了开发的工作量。

另外你应该也注意到了,当一个类中没有代码时可以将大括号省略,比如可以将:

data class Animal(val age: Int, val gender: String){

}

简化为:

data class Animal(val age: Int, val gender: String)

5.5.2:单例类

单例可以说是日常开发中常见的需求了,很多时候我们希望构建一个全局最多只有一个实例的类,在Java中一般会这么写:

public class Animal {
    private static Animal animal;
    private Animal() {
    }
    public synchronized static Animal getInstance() {
        if (animal == null) {
            animal = new Animal();
        }
        return animal;
    }
}

可以看到写法还是繁琐的,在kotlin中只需要:

object Animal {
    fun testFun() {
    }
}

没错又是只有一行代码,kotlin中使用object关键字来声明单例,那么其实现原理是什么呢?我们看看上面代码的字节码反编译为java的结果是什么:

import kotlin.Metadata;
@Metadata(
   mv = {1, 1, 13},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\b?\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004¨\u0006\u0005"},
   d2 = {"LAnimal;", "", "()V", "testFun", "", "LearnKotlin"}
)
public final class Animal {
   public static final Animal INSTANCE;
   public final void testFun() {
   }
   private Animal() {
   }
   static {
      Animal var0 = new Animal();
      INSTANCE = var0;
   }
}

可以看到,object关键字的背后是kotlin为我们自动实现了一套饿汉式的单例代码。使用该单例类也很简单:

Animal.testFun()

可以看到,直接通过类名调用方法即可。

6:总结

本文我们介绍了Kotlin的基础知识,涉及到变量和函数、程序的逻辑控制、面向对象等知识点,希望大家可以熟练掌握,下一篇文章我们将介绍kotlin的一些高级特性,比如lambda编程、标准函数和静态方法、拓展函数、高阶函数等知识点,欢迎大家关注。

相关推荐

为什么劝你不要买Switch OLED?(现在买switch oled划算吗)

那么在聊我们自己的观点前,还是先来看看这款任天堂SwitchOLED款式究竟带来了哪些变化吧。SwitchOLED已经把它最大的特点之一写到了名字里——OLED。这款产品改动最大的地方,就是在维...

新游戏、怀旧机!没有Switch新机的任天堂还能俘虏玩家们的心吗?丨C位

6月16日凌晨,日本电子游戏巨头任天堂在E3游戏展会上举行了发布会。翘首以盼的SwitchPro并未亮相,截止发稿,任天堂股价跌2.44%。但玩家们最为期待的《塞尔达:荒野之息2》将于2022年推出...

腾讯引进Nintendo Switch (OLED版)开启预售 多重满足您的娱乐需求

1月4日,腾讯引进NintendoSwitch(OLED版)开启预售,并将于1月11日正式发售。NintendoSwitch(OLED版)是NintendoSwitch的全新款式,配置色彩艳丽的...

股东大会上任天堂考虑移植更多WiiU和GC游戏到Switch

任天堂股东大会上有任天堂的忠实小股东玩家提议想在Switch玩到WiiU以及GC的经典游戏,对于这个问题,官方给了正面的回应。官方表示目前皮克敏等部分游戏已经可以在switch上玩了,今后会认真考虑玩...

《野狗子》M站均分低至60分!IGN仅给5分、VGC感觉像是PS3游戏

外山圭一郎工作室首部作品《野狗子》全球媒体口碑已解禁,总体评价一般,目前M站均分已降低至60分,21条评价,好评5条,中评14条,差评2条。IGN为其打出5分评价。《野狗子》的特色在于一些有趣的附身交...

《EA SPORTS FC 25》加入任天堂游戏试玩会,Switch版可免费体验

近日,EASPORTS宣布其最新力作《EASPORTSFC25》的Switch版本已正式加入任天堂游戏试玩会。即日起至3月2日,所有NintendoSwitchOnline订阅用户均可限时...

Double Kill!马里奥乐园+Switch能解任天堂焦虑吗?丨C位

近日,“超级任天堂世界”主题乐园在大阪环球影城开园,“超级马里奥之父”宫本茂现身揭幕仪式。任天堂近来喜事连连,2020年财年前九个月实现营收838亿元,贡献最大的Switch销量远超索尼PS5与微...

迷你主机、Switch好搭子:16寸4K超亮QLED CFORCE便携屏值得入手吗

一、迷你主机、Switch好搭子...

怎样查看Switch的“主机序列号信息”

小时候看到游戏机就走不动,现在玩游戏越来越方便了,比如Switch.今天讲讲怎样查看Switch的“主机序列号信息”。第一步:点击【设置】...

Switch版《EA SPORTS FC 25》容量相比前作缩水

备受期待的Switch版足球游戏《EASPORTSFC25》即将发布,根据任天堂官方网站的游戏信息显示,与前作《EASPORTSFC24》相比,游戏容量有所下降。在任天堂官方网站可以查到,...

switch双系统升级注意点(switch双系统升级注意点是什么)

升级系统有风险,建议只有实在想玩的游戏玩不了的时候再升级。1、针对双系统进行,单系统不适用。2、国行系统同pj系统的升级是分开的,互不干涉。国行系统进入后直接升级即可。3、升级之前,建议先做好各类备份...

《鬼泣4:特别版》游戏评测:全家老小齐上阵

游戏名称:鬼泣4:特别版英文名称:DevilMayCry?4SpecialEdition游戏类型:动作游戏ACT制作公司:CAPCOMCo.,Ltd.发行公司:CAPCOMCo.,L...

最好不要在超过35°C的环境温度里玩你的掌机

随着进入“初伏”,天气越发酷热,今年全球高温尤为严重。Valve对此发布了一个安全警告,告诉玩家SteamDeck可以在哪些温度下安全运行。Valve指出,SteamDeck的最佳工作环...

任天堂回应股东玩家 考虑Switch回溯游玩WiiU以及GC游戏

今日有任天堂的忠实小股东玩家提议想在Switch玩到WiiU以及GC的经典游戏,官方回应称正在考虑中,敬请期待。·当然,Switch回溯游玩WiiU以及GC游戏的方式有任天堂的在线服务直接游玩官方优...

Switch 2神秘C键用途曝光!或能连接初代NS手柄

直到近日,游戏圈内的风云人物、知名爆料人extas1s站了出来,带来一则令人颇感意外的消息。extas1s爆料称,玩家有望借助这个神秘的C按钮,实现初代Switch与Switch2...