首页 > 解决方案 > 类型更改未按预期运行

问题描述

我正在解决一个编码问题,要求检查给定数组是否包含给定字符串的所有旋转,我最初想出了这个解决方案:

type myArr []string

func ContainAllRots(strng string, arr []string) bool { 
   if strng == "" {
      return true
    }

   arr = myArr(arr)

   for i := 0; i < len(strng); i++ {
      if !arr.Contains(strng[i:] + strng[:i]) {
        return false
      }
    }

    return true
}

func (a myArr) Contains(strng string) bool {
  for _,s := range a {  
    if s == strng {
      return true
    }
  }

  return false

}

请忽略这样一个事实,即这可能不是给定问题的最佳/最有效的解决方案,但是是的,所以我收到了以下错误消息:

arr.Contains undefined (type []string has no field or method Contains)

我想用这条线arr = myArr(arr)我会改变类型,arr因此能够调用Contains它的方法,但我猜逻辑不起作用。谁能告诉我这里发生了什么以及为什么我没有将我的新自定义类型分配回arr

标签: gotypescasting

解决方案


问题”

在大多数情况下,Go 是一种具有静态类型系统(或“具有静态类型”)的语言。
除此之外,这意味着程序中的任何变量都具有声明变量的隐式类型
换句话说,变量的类型并没有以某种方式存储其中,因此不能通过为其分配另一个类型的值来更改。

因此,如果你有

type myArr []string

func foo(arr []string) {
    arr = myArr(arr)
}

赋值是非法的,否则意味着将变量的类型更改arrmyArr.

你能做些什么呢?

在这种情况下使用的方法是简单地使用另一个合适类型的变量。

这看起来像是在浪费资源,但

  • 这种浪费可以忽略不计,无论如何不要优化,这并没有被证明是缓慢的。
  • 您尝试的重新分配可能看起来很整洁,但同时它可能会让读者感到困惑:因为相同的变量在分配之前和之后会有不同的方法集。

为了完整起见,我们应该提到 Go 有特殊的方法,它允许程序员实际拥有可以在运行时更改其类型的变量;这些方法由接口提供。

例如,下面代码中的两个赋值都是完全合法的:

type I interface {
  Foo()
}

type A struct{}

func (a A) Foo() {}

type B struct{}

func (b B) Foo() {}

var v I

v = A{}
v = B{}

该变量v的类型I是接口类型,因此它应该包含接口值。这两个赋值都将变量
的所谓动态类型v分别更改为toA和然后 to B,而其静态类型保持为I

我会注意到,在您的特定情况下,不需要使用接口,但这是需要学习的东西。


推荐阅读