我有2个go函数,例如以下
func removeL2McEntry(a []api.L2McEntry, index int) []api.L2McEntry {
a = append(a[:index], a[index+1:]...)
element
return a[:len(a)]
}
func removeVlagBasedGroup(a []api.VlanPortBased, index int) []api.VlanPortBased {
a = append(a[:index], a[index+1:]...)
return a[:len(a)]
}
如您所见,这两个功能都在做相同的工作。但是我需要将它们分开,因为函数的输出和输入是不同的类型。
我尝试过:
func removeSlice(a interface{}, idx int) interface{} {
switch v := a.(type) {
case []string:
v = append(v[:idx], v[idx+1:]...)
fmt.Println("is ary", v)
return v[:len(v)]
case []int:
v = append(v[:idx], v[idx+1:]...)
fmt.Println("is ary", v)
return v[:len(v)]
default:
}
return nil
}
但是用这种方式的重复代码太多了。 有什么方法可以使它成为一个功能并减少重复的代码?
谢谢。
答案 0 :(得分:2)
正如阿德里安(Adrian)所说,从切片中删除元素通常是一行代码:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
var kmlLayer = new google.maps.KmlLayer();
var src = 'https://www.voanaboa.pt/Files/downloads/Regulamento-RPA-ver-5.0.kmz';
var kmlLayer = new google.maps.KmlLayer(src, {
//suppressInfoWindows: true,
preserveViewport: false,
map: map
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=geometry&callback=initMap"
async defer></script>
为它编写一个函数真的不值得,只需在需要的地方使用此代码段即可。
如果确实需要创建一个可以处理任何切片类型的函数,则可以使用反射来创建它。但是使用它时,您将必须在结果上使用类型断言,因为该函数只能返回静态类型a = append(a[:i], a[i+1]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
。比在您的具体切片值上使用上面的代码段还要慢!
可以使用reflect
包“复制”上述删除步骤。切片是Value.Slice()
方法,附加操作是reflect.AppendSlice()
函数。
这是它的外观(省略类型和绑定检查):
interface{}
测试:
func remove(s interface{}, i int) interface{} {
v := reflect.ValueOf(s)
return reflect.AppendSlice(v.Slice(0, i), v.Slice(i+1, v.Len())).Interface()
}
输出(在Go Playground上尝试):
is := []int{0, 1, 2, 3}
is = remove(is, 2).([]int)
fmt.Printf("%#v\n", is)
ss := []string{"0", "1", "2", "3"}
ss = remove(ss, 2).([]string)
fmt.Printf("%#v\n", ss)
但是再说一次:我不建议任何人使用此(尽管有效)代码,只需直接使用原始代码段删除该元素即可。