分类 技术 下的文章

这篇快速指南是为了帮助你修复 “yay error: while loading shared libraries: libalpm.so.12” 错误。

如果你在系统中运行 Arch Linux 的时间比较长,那么由于其滚动发布性质以及你的硬件支持,程序可能会损坏。 如果你使用 AUR 助手 Yay,那么有时,由于其他软件包的多次安装升级,Yay 可能会损坏。

Yay 助手一般是非常稳定的,但有时它会被搞乱,在修复好之前,你不能使用它安装任何程序。而其中一个令人头疼的错误是这样的:

yay: error while loading shared libraries: libalpm.so.12: cannot open shared object file: No such file or directory

这个错误特别是在升级到 pacman 6.0 后出现的,因为共享库不兼容。

error while loading shared libraries - yay

如何解决 “yay: error while loading shared libraries: libalpm.so.12”

这个错误只能通过完全卸载 yay 来解决,包括它的依赖。然后重新安装 yay

没有其他方法来解决这个错误。

我们已经有一个 如何安装 Yay 的指南,然而,以下是修复的步骤。

从 AUR 克隆 yay 仓库并构建。在终端窗口中依次运行以下命令。

cd /tmp
git clone 'https://aur.archlinux.org/yay.git'
cd /tmp/yay
makepkg -si
cd ~
rm -rf /tmp/yay/

安装完成后,你可以尝试运行给你带来这个错误的命令。然后就好了。如果你仍然有这个错误,请在下面的评论区告诉我。

很多人都遇到了这个问题,网络上有 几个讨论。以上是解决这个错误的唯一办法。而且我在任何地方都找不到这个问题的确切根源,除了它是在 pacman 6.0 更新后开始的。


via: https://www.debugpoint.com/2021/07/yay-error-libalpm-so-12/

作者:Arindam 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

机器学习(ML)就是,分析一组数据以预测结果。Python 被认为是 ML 的最佳编程语言选择之一。在本文中,我们将讨论使用 Python 进行分类的机器学习。

machine-learning-classification

假设你想教孩子区分苹果和橙子。有多种方法可以做到这一点。你可以让孩子触摸这两种水果,让他们熟悉形状和柔软度。你还可以向她展示苹果和橙子的多个例子,以便他们可以直观地发现差异。这个过程的技术等价物被称为机器学习。

机器学习教计算机解决特定问题,并通过经验变得更好。这里讨论的示例是一个分类问题,其中机器被赋予各种标记示例,并期望使用它从标记样本中获得的知识来对未标记样本进行标记。机器学习问题也可以采用回归的形式,其中期望根据已知样本及其解决方案来预测给定问题的 实值 real-valued 解决方案。 分类 Classification 回归 Regression 被广泛称为 监督学习 supervised learning 。机器学习也可以是 无监督 unsupervised 的,机器识别未标记数据中的模式,并形成具有相似模式的样本集群。机器学习的另一种形式是 强化学习 reinforcement learning ,机器通过犯错从环境中学习。

分类

分类是根据从已知点获得的信息来预测一组给定点的标签的过程。与一个数据集相关的类别或标签可以是二元的,也可以是多元的。举例来说,如果我们必须给与一个句子相关的情绪打上标签,我们可以把它标记为正面、负面或中性。另一方面,我们必须预测一个水果是苹果还是橘子的问题将有二元标签。表 1 给出了一个分类问题的样本数据集。

在该表中,最后一列的值,即贷款批准,预计将基于其他变量进行预测。在接下来的部分中,我们将学习如何使用 Python 训练和评估分类器。

年龄信用等级工作拥有房产贷款批准
35
32
22一般
42

表 1

训练和评估分类器

为了训练 分类器 classifier ,我们需要一个包含标记示例的数据集。尽管本节不涉及清理数据的过程,但建议你在将数据集输入分类器之前阅读各种数据预处理和清理技术。为了在 Python 中处理数据集,我们将导入 pandas 包和 数据帧 DataFrame 结构。然后,你可以从多种分类算法中进行选择,例如 决策树 decision tree 支持向量分类器 support vector classifier 随机森林 random forest 、XG boost、ADA boost 等。我们将看看随机森林分类器,它是使用多个决策树形成的集成分类器。

from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
 
classifier = RandomForestClassifier()
 
#creating a train-test split with a proportion of 70:30
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
 
classifier.fit(X_train, y_train) # 在训练集上训练分类器
 
y_pred = classifier.predict(X_test) # 用未知数据评估分类器
 
print("Accuracy: ", metrics.accuracy_score(y_test, y_pred)) # 用测试计划中的实际值比较准确率

虽然这个程序使用准确性作为性能指标,但应该使用多种指标的组合,因为当测试集不平衡时,准确性往往会产生非代表性的结果。例如,如果模型对每条记录都给出了相同的预测,而用于测试模型的数据集是不平衡的,即数据集中的大多数记录与模型预测的类别相同,我们就会得到很高的准确率。

调整分类器

调优是指修改模型的 超参数 hyperparameter 值以提高其性能的过程。超参数是可以改变其值以改进算法的学习过程的参数。

以下代码描述了随机搜索超参数调整。在此,我们定义了一个搜索空间,算法将从该搜索空间中选择不同的值,并选择产生最佳结果的那个:

from sklearn.model_selection import RandomizedSearchCV

#define the search space
min_samples_split = [2, 5, 10]
min_samples_leaf = [1, 2, 4]
grid = {‘min_samples_split’ : min_samples_split, ‘min_samples_leaf’ : min_samples_leaf}

classifier = RandomizedSearchCV(classifier, grid, n_iter = 100)

# n_iter 代表从搜索空间提取的样本数
# result.best_score 和 result.best_params_ 可以用来获得模型的最佳性能,以及参数的最佳值

classifier.fit(X_train, y_train)

投票分类器

你也可以使用多个分类器和它们的预测来创建一个模型,根据各个预测给出一个预测。这个过程(只考虑为每个预测投票的分类器的数量)被称为硬投票。软投票是一个过程,其中每个分类器产生一个给定记录属于特定类别的概率,而投票分类器产生的预测是获得最大概率的类别。

下面给出了一个创建软投票分类器的代码片段:

soft_voting_clf = VotingClassifier(
estimators=[(‘rf’, rf_clf), (‘ada’, ada_clf), (‘xgb’, xgb_clf), (‘et’, et_clf), (‘gb’, gb_clf)],
voting=’soft’)
soft_voting_clf.fit(X_train, y_train)

这篇文章总结了分类器的使用,调整分类器和结合多个分类器的结果的过程。请将此作为一个参考点,详细探讨每个领域。


via: https://www.opensourceforu.com/2022/05/machine-learning-classification-using-python/

作者:Gayatri Venugopal 选题:lkxed 译者:geekpi 校对:turbokernel

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果你使用 apt 命令在终端中安装软件包,你将看到各种输出。

如果你注意并查看输出,有时你会注意到一条消息:

package_name set to manually installed

你有没有想过这条消息是什么意思,为什么你没有在所有包上看到它?让我在本篇中分享一些细节。

理解 “软件包被标记为手动安装”

当你尝试安装已安装的库或开发包时,你会看到此消息。此依赖包是与另一个包一起自动安装的。如果删除了主包,则使用 apt autoremove 命令删除依赖包。

但是由于你试图显式安装依赖包,你的 Ubuntu 系统认为你需要这个包独立于主包。因此,该软件包被标记为手动安装,因此不会自动删除。

不是很清楚,对吧?以 在 Ubuntu 上安装 VLC 为例。

由于主 VLC 包依赖于许多其他包,因此这些包会自动安装。

installing vlc with apt ubuntu

如果你检查名称中包含 vlc已安装软件包列表,你会看到除了 VLC,其余都标记为“自动”。这表明这些软件包是(跟着 vlc)自动安装的,当 VLC 被卸载时,它们将使用 apt autoremove 命令自动删除。

list installed packages vlc ubuntu

现在假设你出于某种原因考虑安装 vlc-plugin-base。如果你在其上运行 apt install 命令,系统会告诉你该软件包已安装。同时,它将标记从自动更改为手动,因为系统认为在尝试手动安装表明你明确需要此 vlc-plugin-base

package set manually

可以看到它的状态已经从 [installed,automatic] 变成了 [installed]

listing installed packages with vlc

现在,让我删除 VLC 并运行 autoremove 命令。你可以看到 vlc-plugin-base 不在要删除的软件包列表中。

autoremove vlc ubuntu

再次检查已安装软件包的列表。vlc-plugin-base 仍然安装在系统上。

listing installed packages after removing vlc

你可以在这里看到另外两个与 VLC 相关的包。这些是 vlc-plugin-base 包的依赖项,这就是为什么它们也存在于系统上但标记为 automatic 的原因。

我相信现在有了这些例子,事情就更清楚了。让我给你一个额外的技巧。

将包重置为自动

如果包的状态从自动更改为手动,你可以通过以下方式将其设置回自动:

sudo apt-mark auto package_name

set package to automatic

结论

这不是一个重大错误,也不会阻止你在系统中进行工作。但是,了解这些小事会增加你的知识。

好奇心可能会害死猫,但它会让企鹅变得更聪明。这是为这篇原本枯燥的文章增添幽默感的原始引述 : )

如果你想阅读更多这样的文章,这些文章可能看起来微不足道,但可以帮助你更好地了解您的 Linux 系统,请告诉我。


via: https://itsfoss.com/package-set-manually-installed/

作者:Abhishek Prakash 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

编程语言往往具有许多共同特征。学习一门新语言的好方法是去写一个熟悉的程序。在本文中,我将会使用 Awk 编写一个“猜数字”程序来展示熟悉的概念。

当你学习一门新的编程语言时,最好把重点放在大多数编程语言都有的共同点上:

  • 变量 —— 存储信息的地方
  • 表达式 —— 计算的方法
  • 语句 —— 在程序中表示状态变化的方法

这些概念是大多是编程语言的基础。

一旦你理解了这些概念,你就可以开始把其他的弄清楚。例如,大多数语言都有由其设计所支持的“处理方式”,这些方式在不同语言之间可能有很大的不同。这些方法包括模块化(将相关功能分组在一起)、声明式与命令式、面向对象、低级与高级语法特性等等。许多程序员比较熟悉的是编程“仪式”,即,在处理问题之前设置场景所需花费的工作。据说 Java 编程语言有一个源于其设计的重要仪式要求,就是所有代码都在一个类中定义。

但从根本上讲,编程语言通常有相似之处。一旦你掌握了一种编程语言,就可以从学习另一种语言的基本知识开始,品味这种新语言的不同之处。

一个好方法是创建一组基本的测试程序。有了这些,就可以从这些相似之处开始学习。

你可以选择创建的一个测试程序是“猜数字”程序。电脑从 1 到 100 之间选择一个数字,让你猜这个数字。程序一直循环,直到你猜对为止。

“猜数字”程序练习了编程语言中的几个概念:

  • 变量
  • 输入
  • 输出
  • 条件判断
  • 循环

这是学习一门新的编程语言的一个很好的实践实验。

:本文改编自 Moshe Zadka 在 Julia 中使用这种方法和 Jim Hall在 Bash 中使用这种方法的文章。

在 awk 程序中猜数

让我们编写一个实现“猜数字”游戏的 Awk 程序。

Awk 是动态类型的,这是一种面向数据转换的脚本语言,并且对交互使用有着令人惊讶的良好支持。Awk 出现于 20 世纪 70 年代,最初是 Unix 操作系统的一部分。如果你不了解 Awk,但是喜欢电子表格,这就是一个你可以 去学习 Awk 的信号!

您可以通过编写一个“猜数字”游戏版本来开始对 Awk 的探索。

以下是我的实现(带有行号,以便我们可以查看一些特定功能):

     1    BEGIN {
     2        srand(42)
     3        randomNumber = int(rand() * 100) + 1
     4        print "random number is",randomNumber
     5        printf "guess a number between 1 and 100\n"
     6    }
     7    {
     8        guess = int($0)
     9        if (guess < randomNumber) {
    10            printf "too low, try again:"
    11        } else if (guess > randomNumber) {
    12            printf "too high, try again:"
    13        } else {
    14            printf "that's right\n"
    15            exit
    16        }
    17    }

我们可以立即看到 Awk 控制结构与 C 或 Java 的相似之处,但与 Python 不同。 在像 if-then-elsewhile 这样的语句中,thenelsewhile 部分接受一个语句或一组被 {} 包围的语句。然而,Awk 有一个很大的区别需要从一开始就了解:

根据设计,Awk 是围绕数据管道构建的。

这是什么意思呢?大多数 Awk 程序都是一些代码片段,它们接收一行输入,对数据做一些处理,然后将其写入输出。认识到这种转换管道的需要,Awk 默认情况下提供了所有的转换管道。让我们通过关于上面程序的一个基本问题来探索:“从控制台读取数据”的结构在哪里?

答案是——“内置的”。特别的,第 7-17 行告诉 Awk 如何处理被读取的每一行。在这种情况下,很容易看到第 1-6 行是在读取任何内容之前被执行的。

更具体地说,第 1 行上的 BEGIN 关键字是一种“模式”,在本例中,它指示 Awk 在读取任何数据之前,应该先执行 { ... }BEGIN 后面的内容。另一个类似的关键字 END,在这个程序中没有被使用,它指示 Awk 在读取完所有内容后要做什么。

回到第 7-17 行,我们看到它们创建了一个类似代码块 { ... } 的片段,但前面没有关键字。因为在 { 之前没有任何东西可以让 Awk 匹配,所以它将把这一行用于接收每一行输入。每一行的输入都将由用户输入作为猜测。

让我们看看正在执行的代码。首先,是在读取任何输入之前发生的序言部分。

在第 2 行,我们用数字 42 初始化随机数生成器(如果不提供参数,则使用系统时钟)。为什么要用 42?当然要选 42!#The_Hitchhiker's_Guide_to_the_Galaxy) 第 3 行计算 1 到 100 之间的随机数,第 4 行输出该随机数以供调试使用。第 5 行邀请用户猜一个数字。注意这一行使用的是 printf,而不是 print。和 C 语言一样,printf 的第一个参数是一个用于格式化输出的模板。

既然用户知道程序需要输入,她就可以在控制台上键入猜测。如前所述,Awk 将这种猜测提供给第 7-17 行的代码。第 18 行将输入记录转换为整数;$0 表示整个输入记录,而 $1 表示输入记录的第一个字段,$2 表示第二个字段,以此类推。是的,Awk 使用预定义的分隔符(默认为空格)将输入行分割为组成字段。第 9-15 行将猜测结果与随机数进行比较,打印适当的响应。如果猜对了,第 15 行就会从输入行处理管道中提前退出。

就这么简单!

考虑到 Awk 程序不同寻常的结构,代码片段会对特定的输入行配置做出反应,并处理数据,让我们看看另一种结构,看看过滤部分是如何工作的:

     1    BEGIN {
     2        srand(42)
     3        randomNumber = int(rand() * 100) + 1
     4        print "random number is",randomNumber
     5        printf "guess a number between 1 and 100\n"
     6    }
     7    int($0) < randomNumber {
     8        printf "too low, try again: "
     9    }
    10    int($0) > randomNumber {
    11        printf "too high, try again: "
    12    }
    13    int($0) == randomNumber {
    14        printf "that's right\n"
    15        exit
    16    }

第 1–6 行代码没有改变。但是现在我们看到第 7-9 行是当输入整数值小于随机数时执行的代码,第 10-12 行是当输入整数值大于随机数时执行的代码,第 13-16 行是两者相等时执行的代码。

这看起来“很酷但很奇怪” —— 例如,为什么我们会重复计算 int($0)?可以肯定的是,用这种方法来解决问题会很奇怪。但这些模式确实是分离条件处理的非常好的方式,因为它们可以使用正则表达式或 Awk 支持的任何其他结构。

为了完整起见,我们可以使用这些模式将普通的计算与只适用于特定环境的计算分离开来。下面是第三个版本:

     1    BEGIN {
     2        srand(42)
     3        randomNumber = int(rand() * 100) + 1
     4        print "random number is",randomNumber
     5        printf "guess a number between 1 and 100\n"
     6    }
     7    {
     8        guess = int($0)
     9    }
    10    guess < randomNumber {
    11        printf "too low, try again: "
    12    }
    13    guess > randomNumber {
    14        printf "too high, try again: "
    15    }
    16    guess == randomNumber {
    17        printf "that's right\n"
    18        exit
    19    }

认识到这一点,无论输入的是什么值,都需要将其转换为整数,因此我们创建了第 7-9 行来完成这一任务。现在第 10-12、13-15 和 16-19 行这三组代码,都是指已经定义好的变量 guess,而不是每次都对输入行进行转换。

让我们回到我们想要学习的东西列表:

  • 变量 —— 是的,Awk 有这些;我们可以推断出,输入数据以字符串形式输入,但在需要时可以转换为数值
  • 输入 —— Awk 只是通过它的“数据转换管道”的方式发送输入来读取数据
  • 输出 —— 我们已经使用了 Awk 的 printprintf 函数来将内容写入输出
  • 条件判断 —— 我们已经学习了 Awk 的 if-then-else 和对应特定输入行配置的输入过滤器
  • 循环 —— 嗯,想象一下!我们在这里不需要循环,这还是多亏了 Awk 采用的“数据转换管道”方法;循环“就这么发生了”。注意,用户可以通过向 Awk 发送一个文件结束信号(当使用 Linux 终端窗口时可通过快捷键 CTRL-D)来提前退出管道。

不需要循环来处理输入的重要性是非常值得的。Awk 能够长期保持存在的一个原因是 Awk 程序是紧凑的,而它们紧凑的一个原因是不需要从控制台或文件中读取的那些格式代码。

让我们运行下面这个程序:

$ awk -f guess.awk
random number is 25
guess a number between 1 and 100: 50
too high, try again: 30
too high, try again: 10
too low, try again: 25
that's right
$

我们没有涉及的一件事是注释。Awk 注释以 # 开头,以行尾结束。

总结

Awk 非常强大,这种“猜数字”游戏是入门的好方法。但这不应该是你探索 Awk 的终点。你可以看看 Awk 和 Gawk(GNU Awk)的历史,Gawk 是 Awk 的扩展版本,如果你在电脑上运行 Linux,可能会有这个。或者,从它的原始开发者那里阅读关于 最初版本 的各种信息。

你还可以 下载我们的备忘单 来帮你记录下你所学的一切。

Awk 备忘单

via: https://opensource.com/article/21/1/learn-awk

作者:Chris Hermansen 选题:lujun9972 译者:FYJNEVERFOLLOWS 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解使用数组和切片在 Go 中存储数据的优缺点,以及为什么其中一个更好。

在本系列的第四篇文章中,我将解释 Go 数组和切片,包括如何使用它们,以及为什么你通常要选择其中一个而不是另一个。

数组

数组是编程语言中最流行的数据结构之一,主要原因有两个:一是简单易懂,二是可以存储许多不同类型的数据。

你可以声明一个名为 anArray 的 Go 数组,该数组存储四个整数,如下所示:

anArray := [4]int{-1, 2, 0, -4}

数组的大小应该在它的类型之前声明,而类型应该在声明元素之前定义。len() 函数可以帮助你得到任何数组的长度。上面数组的大小是 4。

如果你熟悉其他编程语言,你可能会尝试使用 for 循环来遍历数组。Go 当然也支持 for 循环,不过,正如你将在下面看到的,Go 的 range 关键字可以让你更优雅地遍历数组或切片。

最后,你也可以定义一个二维数组,如下:

twoD := [3][3]int{
  {1, 2, 3},
  {6, 7, 8},
  {10, 11, 12}}

arrays.go 源文件中包含了 Go 数组的示例代码。其中最重要的部分是:

for i := 0; i < len(twoD); i++ {
  k := twoD[i]
  for j := 0; j < len(k); j++ {
    fmt.Print(k[j], " ")
  }
  fmt.Println()
}

for _, a := range twoD {
  for _, j := range a {
    fmt.Print(j, " ")
  }
  fmt.Println()
}

通过上述代码,我们知道了如何使用 for 循环和 range 关键字迭代数组的元素。arrays.go 的其余代码则展示了如何将数组作为参数传递给函数。

以下是 arrays.go 的输出:

$ go run arrays.go
Before change(): [-1 2 0 -4]
After change(): [-1 2 0 -4]
1 2 3
6 7 8
10 11 12
1 2 3
6 7 8
10 11 12

这个输出告诉我们:对函数内的数组所做的更改,会在函数退出后丢失。

数组的缺点

Go 数组有很多缺点,你应该重新考虑是否要在 Go 项目中使用它们。

首先,数组定义之后,大小就无法改变,这意味着 Go 数组不是动态的。简而言之,如果你需要将一个元素添加到一个没有剩余空间的数组中,你将需要创建一个更大的数组,并将旧数组的所有元素复制到新数组中。

其次,当你将数组作为参数传递给函数时,实际上是传递了数组的副本,这意味着你对函数内部的数组所做的任何更改,都将在函数退出后丢失。

最后,将大数组传递给函数可能会很慢,主要是因为 Go 必须创建数组的副本。

以上这些问题的解决方案,就是使用 Go 切片。

切片

Go 切片与 Go 数组类似,但是它没有后者的缺点。

首先,你可以使用 append() 函数将元素添加到现有切片中。此外,Go 切片在内部使用数组实现,这意味着 Go 中每个切片都有一个底层数组。

切片具有 capacity 属性和 length 属性,它们并不总是相同的。切片的长度与元素个数相同的数组的长度相同,可以使用 len() 函数得到。切片的容量是当前为切片分配的空间,可以使用 cap() 函数得到。

由于切片的大小是动态的,如果切片空间不足(也就是说,当你尝试再向切片中添加一个元素时,底层数组的长度恰好与容量相等),Go 会自动将它的当前容量加倍,使其空间能够容纳更多元素,然后将请求的元素添加到底层数组中。

此外,切片是通过引用传递给函数的,这意味着实际传递给函数的是切片变量的内存地址,这样一来,你对函数内部的切片所做的任何修改,都不会在函数退出后丢失。因此,将大切片传递给函数,要比将具有相同数量元素的数组传递给同一函数快得多。这是因为 Go 不必拷贝切片 —— 它只需传递切片变量的内存地址。

slice.go 源文件中有 Go 切片的代码示例,其中包含以下代码:

package main

import (
  "fmt"
)

func negative(x []int) {
  for i, k := range x {
    x[i] = -k
  }
}

func printSlice(x []int) {
  for _, number := range x {
    fmt.Printf("%d ", number)
  }
  fmt.Println()
}

func main() {
  s := []int{0, 14, 5, 0, 7, 19}
  printSlice(s)
  negative(s)
  printSlice(s)

  fmt.Printf("Before. Cap: %d, length: %d\n", cap(s), len(s))
  s = append(s, -100)
  fmt.Printf("After. Cap: %d, length: %d\n", cap(s), len(s))
  printSlice(s)

  anotherSlice := make([]int, 4)
  fmt.Printf("A new slice with 4 elements: ")
  printSlice(anotherSlice)
}

切片和数组在定义方式上的最大区别就在于:你不需要指定切片的大小。实际上,切片的大小取决于你要放入其中的元素数量。此外,append() 函数允许你将元素添加到现有切片 —— 请注意,即使切片的容量允许你将元素添加到该切片,它的长度也不会被修改,除非你调用 append()。上述代码中的 printSlice() 函数是一个辅助函数,用于打印切片中的所有元素,而 negative() 函数将切片中的每个元素都变为各自的相反数。

运行 slice.go 将得到以下输出:

$ go run slice.go
0 14 5 0 7 19
0 -14 -5 0 -7 -19
Before. Cap: 6, length: 6
After. Cap: 12, length: 7
0 -14 -5 0 -7 -19 -100
A new slice with 4 elements: 0 0 0 0

请注意,当你创建一个新切片,并为给定数量的元素分配内存空间时,Go 会自动地将所有元素都初始化为其类型的零值,在本例中为 0(int 类型的零值)。

使用切片来引用数组

Go 允许你使用 [:] 语法,使用切片来引用现有的数组。在这种情况下,你对切片所做的任何更改都将传播到数组中 —— 详见 refArray.go。请记住,使用 [:] 不会创建数组的副本,它只是对数组的引用。

refArray.go 中最有趣的部分是:

func main() {
  anArray := [5]int{-1, 2, -3, 4, -5}
  refAnArray := anArray[:]

  fmt.Println("Array:", anArray)
  printSlice(refAnArray)
  negative(refAnArray)
  fmt.Println("Array:", anArray)
}

运行 refArray.go,输出如下:

$ go run refArray.go
Array: [-1 2 -3 4 -5]
-1 2 -3 4 -5
Array: [1 -2 3 -4 5]

我们可以发现:对 anArray 数组的切片引用进行了操作后,它本身也被改变了。

总结

尽管 Go 提供了数组和切片两种类型,你很可能还是会使用切片,因为它们比 Go 数组更加通用、强大。只有少数情况需要使用数组而不是切片,特别是当你完全确定元素的数量固定不变时。

你可以在 GitHub 上找到 arrays.goslice.gorefArray.go 的源代码。

如果你有任何问题或反馈,请在下方发表评论或在 Twitter 上与我联系。


via: https://opensource.com/article/18/7/introduction-go-arrays-and-slices

作者:Mihalis Tsoukalos 选题:lkxed 译者:lkxed 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

为纪念全球无障碍意识日,让我们了解一下 NVDA 开源屏幕阅读器,以及你该如何参与其中,为所有网络用户提高无障碍性。

屏幕阅读器是辅助技术软件的一个专门领域,它可以阅读并说出计算机屏幕上的内容。完全没有视力的人只是视力障碍者的一小部分,屏幕阅读器软件可以帮助所有群体。屏幕阅读器大多特定于操作系统,供有视觉障碍的人和无障碍培训师使用,以及想要测试网站或应用的无障碍访问程度的开发人员和无障碍顾问。

如何使用 NVDA 屏幕阅读器

WebAIM 屏幕阅读器用户调查 始于 2009 年,一直持续到 2021 年。在第一次调查中,最常用的屏幕阅读器是 JAWS,占 74%。它是微软 Windows 的商业产品,并且是长期的市场领导者。NVDA 当时是一个相对较新的 Windows 开源屏幕阅读器,仅占 8%。快进到 2021 年,JAWS 占 53.7%,NVDA 占 30.7%。

你可以从 NVAccess 网站 下载最新版本的 NVDA。为什么我要使用 NVDA 并将它推荐给我使用微软 Windows 的客户?嗯,它是开源的、速度快、功能强大、易于安装、支持多种语言、可以作为便携式应用运行、拥有庞大的用户群,并且有定期发布新版本的周期。

NVDA 已被翻译成 55 种语言,并在 175 个不同的国家/地区使用。还有一个活跃的开发者社区,拥有自己的 社区插件网站。你选择安装的任何附加组件都将取决于你的需求,并且有很多可供选择,包括常见视频会议平台的扩展。

与所有屏幕阅读器一样,NVDA 有很多组合键需要学习。熟练使用任何屏幕阅读器都需要培训和练习。

Image of NVDA welcome screen

向熟悉计算机和会使用键盘的人教授 NVDA 并不太难。向一个完全初学者教授基本的计算机技能(没有鼠标、触摸板和键盘技能)和使用 NVDA 是一个更大的挑战。个人的学习方式和偏好不同。此外,如果人们只想浏览网页和使用电子邮件,他们可能不需要学习如何做所有事情。NVDA 教程和资源的一个很好的链接来源是 无障碍中心

当你掌握了使用键盘命令操作 NVDA,它就会变得更容易,但是还有一个菜单驱动的系统可以完成许多配置任务。

Image of NVDA menu

测试无障碍性

多年来,屏幕阅读器用户无法访问某些网站一直是个问题,尽管美国残疾人法案(ADA)等残疾人平等立法仍然存在。NVDA 在有视力的社区中的一个很好的用途是用于网站无障碍性测试。NVDA 可以免费下载,并且通过运行便携式版本,网站开发人员甚至不需要安装它。运行 NVDA,关闭显示器或闭上眼睛,看看你在浏览网站或应用时的表现如何。

NVDA 也可用于测试(通常被忽略的)正确 标记 PDF 文档以实现无障碍性 任务。

有几个指南专注于使用 NVDA 进行无障碍性测试。我可以推荐 使用 NVDA 测试网页 和使用 NVDA 评估 Web 无障碍性


via: https://opensource.com/article/22/5/open-source-screen-reader-windows-nvda

作者:Peter Cheer 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出