scala基础学习_方法函数

news2025/1/12 20:23:25

文章目录

  • 方法与函数
    • 函数(又称函数值/匿名函数)
      • 定义方法
        • 注意
      • 单参数函数
      • 多参数函数
      • 函数作为参数传递
    • 方法
    • 将方法转换为函数
    • 方法的返回值
    • 总结

方法与函数

函数(又称函数值/匿名函数)

  • 定义在任何地方:函数可以定义在类的成员中,也可以定义在顶层(即不在任何类或对象中这是scala3特性)。
  • 不能访问类的私有成员:除非函数定义在类内部,否则它不能访问类的私有成员。
  • 是一等公民:函数可以作为值传递,可以赋值给变量,可以存储在数据结构中,可以作为其他函数的参数或返回值。
  • 可以使用函数字面量定义:函数可以使用 => 符号定义匿名函数。

=> 符号在 Scala 中用于定义匿名函数,它提供了一种简洁的方式来定义函数,特别是在需要将函数作为参数传递给其他函数时。匿名函数是函数式编程的重要组成部分,使代码更加灵活和可组合。

在 Scala 中,匿名函数(也称为 lambda 表达式)通常与 val 一起使用,而不是 var。这是因为匿名函数本身是一个值,并且你通常不希望重新赋值给这个函数。

定义方法

val 函数名:函数类型=>返回类型 = (实际传入参数)=>表达式

简洁形式:这种形式的匿名函数直接将参数和表达式放在 => 符号的两侧。这种形式的函数没有函数体,因此它的返回值是 => 右侧表达式的结果。

// 定义参数类型返回类型,定义参数,表达式
val ldsx2: (Int, Int) => Unit = (a, b) => println(a, b)
// 定义参数 参数类型,表达式
val ldsx2 = (a:Int, b:Int) => println(a, b)

带函数体形式:这种形式的匿名函数使用花括号 {} 来定义函数体。函数体中的最后一个表达式是函数的返回值。

val ldsx3: (Int, Int) => Unit = (a, b) => {
  println(a, b)
}

定义部分

(Int, Int) => Unit 是 Scala 中的一种函数类型表示法,它表示一个接受两个 Int 类型参数并返回 Unit 类型结果的函数。这种表示法通常用于定义匿名函数(lambda 表达式)或高阶函数。

具体来说:

  • (Int, Int): 这部分表示函数接受两个参数,这两个参数的类型都是 Int
  • =>: 这个符号表示函数类型。
  • Unit: 这部分表示函数的返回类型。Unit 是 Scala 中的一个特殊类型,表示没有值,类似于 Java 中的 void

因此,(Int, Int) => Unit 表示一个函数类型,这个函数接受两个 Int 类型的参数,并返回 Unit 类型的结果。这意味着这个函数执行一些操作,但不返回任何值。

以下是一个使用 (Int, Int) => Unit 函数类型的例子:

表达式部分

  • (a, b): 这部分定义了匿名函数的参数列表。这个匿名函数接受两个参数,分别是 ab
  • =>: 这个符号表示函数字面量的开始。
  • { println(a, b) }: 这部分是匿名函数的主体,它是一个代码块。这个代码块包含一个表达式 println(a, b),这个表达式打印参数 ab 的值。
注意

在 Scala 中,当匿名函数的主体只包含一个表达式时,花括号 {} 可以省略。同样,当匿名函数只有一个参数时,圆括号 () 也是可选的。这些简化使得代码更简洁,但也保持了代码的可读性。

  1. 花括号 {}
    花括号用于定义匿名函数的主体。当匿名函数的主体只包含一个表达式时,花括号可以省略。例如:

    // 使用花括号
    val result1 = ary.filter( n => { n == 2 })
    
    // 不使用花括号
    val result2 = ary.filter(n => n == 2)
    

    在这两个例子中,n => n == 2 是一个匿名函数,它接受一个参数 n 并返回一个布尔值,表示 n 是否等于 2。当匿名函数的主体只有一个表达式时,花括号是可选的。

  2. 圆括号 ()
    圆括号用于定义匿名函数的参数列表。当匿名函数只有一个参数时,圆括号也是可选的。例如:

    // 使用圆括号
    val result3 = ary.filter((n) => n == 2)
    
    // 不使用圆括号
    val result4 = ary.filter(n => n == 2)
    

    在这两个例子中,n => n == 2(n) => n == 2 都是有效的匿名函数。当匿名函数只有一个参数时,圆括号是可选的。

单参数函数

val square: Int => Int = x => x * x

// 调用匿名函数
println(square(5)) // 输出 25

val square = x:Int => x*x

在这个例子中,square 是一个匿名函数,它接受一个 Int 类型的参数 x,并返回 x 的平方。

多参数函数

val add: (Int, Int) => Int   =     (a, b) => a + b

// 调用匿名函数
println(add(3, 4)) // 输出 7

在这个例子中,add 是一个匿名函数,它接受两个 Int 类型的参数 ab,并返回它们的和。

val add: (Int, Int) => Int = (a, b) => a + b

这行代码定义了一个名为 add 的值,它实际上是一个匿名函数(也称为函数字面量)。下面是详细的语法解释:

  1. val add:
    • val 是一个关键字,用于定义一个不可变的值(类似于常量)。
    • add 是这个值的名称。
  2. : (Int, Int) => Int:
    • 这部分定义了 add 的类型。
    • (Int, Int) 表示这个函数接受两个 Int 类型的参数。
    • => 符号表示函数的参数和返回值之间的映射。
    • Int 表示这个函数返回一个 Int 类型的结果。
    • 因此,(Int, Int) => Int 表示这是一个接受两个 Int 参数并返回 Int 结果的函数类型。
  3. = (a, b) => a + b:
    • = 符号用于将右侧的匿名函数赋值给左侧的 add
    • (a, b) 表示匿名函数的参数列表,其中 ab 是两个 Int 类型的参数。
    • => 符号表示参数和函数体之间的映射。
    • a + b 是函数体,表示将参数 ab 相加并返回结果。

综上所述,这行代码定义了一个名为 add 的值,它是一个接受两个 Int 参数并返回它们之和的匿名函数。你可以像调用普通函数一样调用 add

println(add(3, 4)) // 输出 7

在这个例子中,add(3, 4) 调用了匿名函数 (a, b) => a + b,其中 a 被赋值为 3b 被赋值为 4,函数体 a + b 计算结果为 7,并打印出来。

函数作为参数传递

匿名函数通常用作高阶函数的参数。高阶函数是可以接受函数作为参数或返回函数作为结果的函数。

object Scalafunc {
  def main(args:Array[String]):Unit={
    // 匿名函数定义
    val fc :(Int,Int)=>Int = (a,b) =>a+b
    println(fc(1,2))

    greet("ldsx")

    lambda_func((a,b)=>a+b,1,"3")
  }

  def greet(name: String): Unit = {
    println(s"Hello, $name!")
  }

  def lambda_func(func :(Int,String)=>String,a:Int,b:String):Unit={
    val data = func(a,b)
    println(data)

  }

}

lambda_func中,参数分为二部分,共三个

  1. func :(Int,String)=>String
    • 第一个参数接受匿名函数名称 func
    • 这个参数目是设置好匿名函数名称,确认匿名函数func接受的参数 与返回的数据类型
  2. a:Int,b:String
    • a,bfunc所需的参数,但是需要通过lambda_func传入函数内部给func调用

方法

  • 定义在类或对象中:方法定义在类或对象内部,是类或对象的一部分。
  • 可以访问类的成员:方法可以访问类的私有成员(如变量和其他方法)。
  • 不是一等公民:方法不能直接作为值传递,不能赋值给变量,不能存储在数据结构中,也不能作为其他方法的参数或返回值。
  • 使用 def 关键字定义:方法使用 def 关键字定义。
object Scalafunc {
  val ldsx = "hello"
  def main(args:Array[String]):Unit={
    // 匿名函数定义
    val fc :(Int,Int)=>Int = (a,b) =>a+b
    println(fc(1,2))

    greet("ldsx")
    // 访问成员
    println(ldsx)
  }
  def greet(name: String): Unit = {
    println(s"Hello, $name!")
  }

}

将方法转换为函数

虽然方法不是一等公民,但你可以通过将方法转换为函数来使用它。这可以通过在方法后面加上一个下划线 _ 来实现。

class MyClass {
  def greet(name: String): String = {
    s"Hello, $name!"
  }
}

val myObject = new MyClass
val greetFunction: String => String = myObject.greet _

println(greetFunction("Scala")) // 输出 "Hello, Scala!"

在这个例子中,myObject.greet _greet 方法转换为了一个函数。

方法的返回值

在 Scala 中,函数和方法不需要显式地使用 return 关键字来返回值。Scala 的函数和方法会返回其最后一个表达式的结果

def add(a: Int, b: Int): Int = {
  a + b // 这个表达式的结果会被返回
}
val result = add(3, 4)
println(result) // 输出 7

在 Scala 中,过程方法是一种不返回任何值的方法。过程方法的返回类型是 Unit,你可以省略 Unit,因为编译器可以推断出返回类型。以下是一个过程方法的示例

// 定义Unit过程方法不会有返回值
def fun3(a:String):Unit={
  var info_d = "aaaa"
  info_d
}

// 设置返回值将会返回最后一个表达式 info_d
def fun4(a:String):String={
  var info_d = "aaaa"
  info_d
}

// 当最后一个表达式是print 则报错,因为print
def fun4(a: String): String = {
      var info_d = a
      info_d
      println(info_d)
    }

// 不定义返回值 自动编译判断,当你返回表达式有结果时为过程函数,当返回值时为返回值函数
def fun4(a: String) = {
  var info_d = a
  println(info_d,111)
  a
}

   

总结

  • 方法 是类或对象的一部分,可以访问类的私有成员,但不是一等公民。
  • 函数 可以在任何地方定义,不能直接访问类的私有成员(除非在类内部定义),但它们是一等公民,具有更大的灵活性和功能性。

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

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

相关文章

ELFK日志采集实战

一、日志分析概述 日志分析是运维工程师解决系统故障,发现问题的主要手段 日志主要包括系统日志、应用程序日志和安全日志 系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因 经常分析日志可以了解服务器的负荷&#x…

辅助--Inspector

辅助–Inspector 1.Introduction This manual explains how to use the Inspector. 1.1.Overview Inspector is a Qt-based library that provides functionality to interactively inspect low-level content of the OCAF data model, OCCT viewer and Modeling Data. Thi…

如何播放视频文件

文章目录 1. 概念介绍2. 使用方法2.1 实现步骤2.2 具体细节3. 示例代码4. 内容总结我们在上一章回中介绍了"如何获取文件类型"相关的内容,本章回中将介绍如何播放视频.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 播放视频是我们常用的功能,不过Flutter官方…

R数据分析:多分类问题预测模型的ROC做法及解释

有同学做了个多分类的预测模型,结局有三个类别,做的模型包括多分类逻辑回归、随机森林和决策树,多分类逻辑回归是用ROC曲线并报告AUC作为模型评估的,后面两种模型报告了混淆矩阵,审稿人就提出要统一模型评估指标。那么肯定是统一成ROC了,刚好借这个机会给大家讲讲ROC在多…

【数据库】四、数据库管理与维护

文章目录 四、数据库管理与维护1 安全性管理2 事务概述3 并发控制4 备份与恢复管理 四、数据库管理与维护 1 安全性管理 安全性管理是指保护数据库,以避免非法用户进行窃取数据、篡改数据、删除数据和破坏数据库结构等操作 三个级别认证: 服务器级别…

C语言gdb调试

目录 1.gdb介绍 2.设置断点 2.1.测试代码 2.2.设置函数断点 2.3.设置文件行号断点 2.4.设置条件断点 2.5.多线程调试 3.删除断点 3.1.删除指定断点 3.2.删除全部断点 4.查看变量信息 4.1.p命令 4.2.display命令 4.3.watch命令 5.coredump日志 6.总结 1.gdb介绍…

winform第三方界面开源库AntdUI的使用教程保姆级环境设置篇

1. AntdUI 1.1. 导入项目 1.1.1. 首先新建一个空白的基于.net的Winfrom项目1.1.2. 复制AntdUI中src目录到我们的解决方案下面1.1.3. 解决方案下添加现有项目1.1.4. 添加项目引用 1.2. 编写代码 1.2.1. 改写Form1类,让其继承自public partial class Form1 : AntdUI.W…

记录一下vue2项目优化,虚拟列表vue-virtual-scroll-list处理10万条数据

文章目录 封装BrandPickerVirtual.vue组件页面使用组件属性 select下拉接口一次性返回10万条数据,页面卡死,如何优化??这里使用 分页 虚拟列表(vue-virtual-scroll-list),去模拟一个下拉的内容…

企业开通部署 Azure OpenAI 流程:如何创建一个AI聊天机器人

由于众所周知的原因,国内没法直接调用 OpenAI 接口。 下面我将演示企业如何开通 Azure OpenAI 服务,以及如何使用 C# 调用 Azure OpenAI 接口创建一个 Console 应用程序并实现聊天机器人功能。 1开通 Azure OpenAI 服务 要开通 Azure OpenAI 服务&…

CNN Test Data

由于数据量过大,打不开了 搞一组小的吧。收工睡觉 https://download.csdn.net/download/spencer_tseng/90256048

STM32使用ITM调试_通过仿真器实现串口打印

IDE:CLion MCU: STM32F407VET6 工具:OpenOCD Telnet 一、简介 调试单片机时,如果要打印数据往往需要另接一根线通过USB转TTL接到电脑上。但这样做往往并不方便,尤其是身边没有USB转TTL工具时。这时可以使用单片机自带的ITM单元…

Ubuntu 磁盘修复

Ubuntu 磁盘修复 在 ubuntu 文件系统变成只读模式,该处理呢? 文件系统内部的错误,如索引错误、元数据损坏等,也可能导致系统进入只读状态。磁盘坏道或硬件故障也可能引发文件系统只读的问题。/etc/fstab配置错误,可能…

RT-DETR融合[AAAI2025]的ConSeg中的CDFAPreprocess模块

RT-DETR使用教程: RT-DETR使用教程 RT-DETR改进汇总贴:RT-DETR更新汇总贴 《ConDSeg: A General Medical Image Segmentation Framework via Contrast-Driven Feature Enhancement》 一、 模块介绍 论文链接:https://arxiv.org/abs/2412.083…

线程与互斥锁

一、线程 1、定义 进程的创建、销毁与切换存在着较大的时空开销,因此人们急需一种轻型的进程技术来减少开销。在80年代,线程的概念开始出现,线程被设计成进程的一个执行路径,同一个进程中的线程共享进程的资源,因此系…

如何搭建 Vue.js 开源项目的 CI/CD 流水线

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

uni app 写的 小游戏,文字拼图?文字拼写?不知道叫啥

从下方的偏旁部首中选在1--3个组成上面文章中的文字&#xff0c;完成的文字标红 不喜勿喷 《满江红》 其中用到了两个文件 strdata.json parameters.json 这两个文件太大 放到资源中了 资源文件 <template><view class"wenzi_page_main"><view c…

DBeaver执行本地的sql语句文件避免直接在客户端运行卡顿

直接在客户端运行 SQL 语句和通过加载本地文件执行 SQL 语句可能会出现不同的性能表现&#xff0c;原因可能包括以下几点&#xff1a; 客户端资源使用&#xff1a; 当你在客户端界面直接输入和执行 SQL 语句时&#xff0c;客户端可能会消耗资源来维护用户界面、语法高亮、自动完…

基于STM32的智能电表可视化设计:ESP8266、AT指令集、python后端Flask(代码示例)

一、项目概述 随着智能家居的普及&#xff0c;智能电表作为家庭用电管理的重要工具&#xff0c;能够实时监测电流、电压及功率&#xff0c;并将数据传输至后台进行分析和可视化。本项目以STM32C8T6为核心&#xff0c;结合交流电压电流监测模块、ESP8266 Wi-Fi模块、OLED显示屏…

MySQL 如何赶上 PostgreSQL 的势头?

原文地址 我与 MySQL 社区的前辈交谈时&#xff0c;经常遇到这个问题&#xff1a;「为什么 MySQL 这么棒&#xff0c;而且&#xff08;至少根据 DB-Engines 的计算&#xff09;仍然比 PostgreSQL 更流行&#xff1b;但它的地位在下降&#xff0c;PostgreSQL 却势不可挡地越来越…

关于在windows系统中编译ffmpeg并导入到自己项目中这件事

关于在windows系统中编译ffmpeg并导入到自己项目中这件事 前因&#xff08;可跳过不看&#xff09; 前阵子由于秋招需求&#xff0c;写了一个简易的安卓播放器&#xff0c;最终因为时间问题还有一些功能没有实现着实可惜&#xff0c;如&#xff1a;倍速播放&#xff0c;快进操…